ORFをJavascriptで取得することで、webページ上で計算できるようにします。
目次
アルゴリズム
Pythonで散々実装したので爆速で作っていきます。今回は逆相補鎖まで考えます。
function reverse_complement(seq){
let dst = "";
const map = new Map();
var n = "";
map.set('A','T');
map.set('T','A');
map.set('C','G');
map.set('G','C');
for (let i = seq.length-1;i>-1;i--){
n = map.get(seq[i]);
if (n != undefined){
dst += n;
}
}
return dst;
};
function sanitize(seq){
let dst = "";
const map = new Map();
var n = "";
map.set('A','T');
map.set('T','A');
map.set('C','G');
map.set('G','C');
for (let i = 0;i<seq.length;i++){
n = map.get(seq[i]);
if (n != undefined){
dst += seq[i];
}
}
return dst;
}
function translate(s){
let seq = sanitize(s)
const DNA_Codons = {
"GCT": "A", "GCC": "A", "GCA": "A", "GCG": "A",
"TGT": "C", "TGC": "C",
"GAT": "D", "GAC": "D",
"GAA": "E", "GAG": "E",
"TTT": "F", "TTC": "F",
"GGT": "G", "GGC": "G", "GGA": "G", "GGG": "G",
"CAT": "H", "CAC": "H",
"ATA": "I", "ATT": "I", "ATC": "I",
"AAA": "K", "AAG": "K",
"TTA": "L", "TTG": "L", "CTT": "L", "CTC": "L", "CTA": "L", "CTG": "L",
"ATG": "M",
"AAT": "N", "AAC": "N",
"CCT": "P", "CCC": "P", "CCA": "P", "CCG": "P",
"CAA": "Q", "CAG": "Q",
"CGT": "R", "CGC": "R", "CGA": "R", "CGG": "R", "AGA": "R", "AGG": "R",
"TCT": "S", "TCC": "S", "TCA": "S", "TCG": "S", "AGT": "S", "AGC": "S",
"ACT": "T", "ACC": "T", "ACA": "T", "ACG": "T",
"GTT": "V", "GTC": "V", "GTA": "V", "GTG": "V",
"TGG": "W",
"TAT": "Y", "TAC": "Y",
"TAA": "_", "TAG": "_", "TGA": "_"
}
const numCodons = (seq.length - seq.length%3)/3;
let protein = "";
for (let i = 0;i < numCodons;i ++){
protein += DNA_Codons[seq[3*i] + seq[3*i+1] + seq[3*i+2]]
}
return protein;
}
function orf(seq){
const seq_r = reverse_complement(seq);
var orfs = []
var orf_candidates = "";
for (let i = 0;i<seq.length;i++){
if (seq.slice(i,i+3) == "ATG"){
orf_candidates = translate(seq.slice(i,seq.length)).split("_")
if (orf_candidates.length>1){
orfs.push(orf_candidates[0]);
}
}
if (seq_r.slice(i,i+3) == "ATG"){
orf_candidates = translate(seq_r.slice(i,seq_r.length)).split("_")
if (orf_candidates.length>1){
orfs.push(orf_candidates[0]);
}
}
}
return Array.from(new Set(orfs));
}以下の配列について実行してみます。
const seq = "CGCACTGAGATATGAAAGAAACACGACCTGCTATCCTGTTCGCGTGCTGCTTGTCGTTAGTTAAGAGGGGCGTTCAAGAAACGACAATGGCTTACTGTCCAGGATAGAACCGAAAGAGATCGTGATAACGACGTCCCACTCGCCTAAATTTCAACGGAGGGCTTTAAGATGGAGAACGACGACCTTCCGCGGAGCAGTACGGTAACGCTAATAACATAGCCTCTAGGTTTTGAAGCCAGTAATGCTGAGCGCCGTAGCGATTGGTCCTGGTCCCAGATTCGGCTATCATCTATGTCTTCATATGCCCTCCTCACACGCGGGAATATAGGTACTTTTAAGTAATCAGGAGAGACAATGACGCCTCCTTATACCGTTGTTGATGGAGTTCATGTAAGGAATCAACTGACGCATAGAGGTCCGGGCCAGAGCGCAGGAACAAATGGCACGAGTAAAAGATACACGCTTAACTTAGCTAAGTTAAGCGTGTATCTTTTACTCGTGCCATATCAACTTCTGCGTCCTAGGCCCAACCCTTTAAAAAGTCGAGATAACGTTGAGACTAGTAAAGACTACCGCGTTGTATATGTAAGAGCACTCGGACGACGAGTTCTGAGTGTTGATATAGAGCGTTGTTGCGCTTGTGTCGCTCGAACCGTAAGATGAGTCTAACGGCGCGGTCCGATCGGAACTTGCTTATGAGCCTTCTAGACGATCACTCGATGGCGGTTAATATGTAAACCAAGGGAGGCCATATGGTTTATTCCTTCAGTGGCGCTGCTCCATAATGCTTAGGTATTGGTCCTCTAGCATTCCAGTCACGCGCCATCTGTCTGCGGATGAGGGTCGACGCCGCGAAGCAGGGTGTACAGAACTGACAACGCGCACTATTTGCACTTATAAAATGCGCAAACAGCCCCCGACTTAACTACGTTACCGACGTGGAT"
const result = orf(seq);
for (let i = 0;i<result.length;i++){
console.log(result[i]);
}
>>>
MKETRPAILFACCLSLVKRGVQETTMAYCPG
MAYCPG
MARDWNARGPIPKHYGAAPLKE
MLEDQYLSIMEQRH
MEQRH
MENDDLPRSSTVTLIT
MASLGLHINRHRVIV
MLSAVAIGPGPRFGYHLCLHMPSSHAGI
MSSYALLTRGNIGTFK
MPSSHAGI
MTPPYTVVDGVHVRNQLTHRGPGQSAGTNGTSKRYTLNLAKLSVYLLLVPYQLLRPRPNPLKSRDNVETSKDYRVVYVRALGRRVLSVDIERCCACVARTVR
MEFM
M
MARVKDTRLT
MRQLIPYMNSINNGIRRRHCLS
MNSINNGIRRRHCLS
MKT
MIAESGTRTNRYGAQHYWLQNLEAMLLALPYCSAEGRRSPS
MSLTARSDRNLLMSLLDDHSMAVNM
MSLLDDHSMAVNM
MAVNM
MLLALPYCSAEGRRSPS
MVYSFSGAAP
MLRYWSSSIPVTRHLSADEGRRREAGCTELTTRTICTYKMRKQPPT
MRVDAAKQGVQN
MRKQPPTメチオニンから翻訳開始されるORFが全パターン網羅できています。
WEBサイトに置く方法
html, css, javascriptのみで、WEBサイトから実行できるようにします。
HTML
<!DOCTYPE html>
<html lang="en"></html>
<head>
<html lang="en">
<meta charset="UTF-8">
<title>Reverse comp.</title>
<link rel="stylesheet" href="primer.css">
</head>
<body>
<header>
<div>
<a href="index.html" class="logo">ツールボックス</a>
</div>
<nav>
<ul>
<li><a href="seq.html"> 配列処理ツール</a></li>
<li><a href="primer.html"> プライマ設計ツール</a></li>
<li><a href="plot.html"> グラフ生成ツール</a></li>
<li><a href="mat.html"> 行列計算ツール</a></li>
<li><a href="orf.html">ORF計算ツール</a></li>
</ul>
</nav>
</header>
<div class="container">
<h1>ORF 2.1</h1>
<div class="nice-wrap">
<div class="result">Sequence</div>
<input class="nice-textbox" type="text" id="newText" placeholder="Input Sequence">
<button class="btn_1" id="changeButton">Generate</button>
<br>
<br><br>
<div class="result">Open reading freams</div>
<div class="target"></div>
</div>
</div>
<script src="orf.js"></script>
</body>
</html>
CSS
* {
box-sizing: border-box;
}
header {
position: fixed;
top: 0;
width: 100%;
display: flex;
align-items: center;
justify-content: space-evenly;
background-color: black;
z-index: 100;
}
header .logo{
text-decoration-line: none;
color: aliceblue;
}
header nav ul{
list-style: none;
}
header nav ul li{
display: inline-block;
}
header nav ul li a {
text-decoration: none;
color: rgb(255, 255, 255);
margin-left: 29px;
font-weight: 600;
transition: all 0.3s;
}
header nav ul li a:hover {
color: thistle;
}
header nav ul li .contact{
display: block;
background-color: rgb(107, 14, 128);
padding: 10px 20px;
border-radius: 15px;
}
html, body {
display: flex;
align-items: center;
justify-content: center;
position: relative;
height: auto;
width: auto;
background-color: #1a0026;
/* background: linear-gradient(-20deg, #8d027f 0%, #052968 100%); */
font-family: "Arial", sans-serif;
}
.container h1 {
color: #fff;
text-transform: uppercase;
text-align: center;
font-size: 50px;
padding-bottom: 10%;
}
.nice-wrap {
position: relative;
width: 800px;
height: 100px;
margin: 0 auto;
}
.nice-label {
position: absolute;
top: 15px;
left: 10px;
font-size: 16px;
color: #a0a0a0;
transition: all 0.25s ease;
}
.nice-label.focus {
top: -25px;
left: 5px;
font-size: 14px;
color: #fff;
}
.nice-textbox {
position: relative;
display: block;
width: 800px;
margin-top: 5px;
padding: 15px;
border: none;
border-radius: 5px;
font-size: 16px;
color: #a0a0a0;
outline: none;
}
.target {
border: 2px solid rgb(254, 254, 254);
padding: 10px;
border-radius: 10px; /* 角の丸みを指定 */
color: #fff;
overflow: auto;
}
.target1 {
border: 2px solid rgb(254, 254, 254);
padding: 10px;
border-radius: 10px; /* 角の丸みを指定 */
color: #fff;
overflow: auto;
}
.target2 {
border: 2px solid rgb(254, 254, 254);
padding: 10px;
border-radius: 10px; /* 角の丸みを指定 */
color: #fff;
overflow: auto;
}
.result{
color: #fff;
}
/* CSS */
.btn_1 {
margin-top: 1%;
margin-left: 90%;
background-image: linear-gradient(#f7f8fa ,#e7e9ec);
border-color: #adb1b8 #a2a6ac #8d9096;
border-style: solid;
border-width: 1px;
border-radius: 3px;
box-shadow: rgba(255,255,255,.6) 0 1px 0 inset;
box-sizing: border-box;
color: #0f1111;
cursor: pointer;
display: inline-block;
font-family: "Amazon Ember",Arial,sans-serif;
font-size: 14px;
height: 29px;
font-size: 13px;
outline: 0;
overflow: hidden;
padding: 0 11px;
text-align: center;
text-decoration: none;
text-overflow: ellipsis;
user-select: none;
-webkit-user-select: none;
touch-action: manipulation;
white-space: nowrap;
}
.btn_1:active {
border-bottom-color: #a2a6ac;
}
.btn_1:active:hover {
border-bottom-color: #a2a6ac;
}
.btn_1:hover {
border-color: #a2a6ac #979aa1 #82858a;
}
.btn_1:focus {
border-color: #e77600;
box-shadow: rgba(228, 121, 17, .5) 0 0 3px 2px;
outline: 0;
}
.container{
margin-top: 20%;
}
実行結果


