<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>REBELSCIENCE</title><link>https://rebelscience.club/</link><description>Bioinformatics, Programming and Open-Source Science</description><item><title>DNA Toolkit Part 5, 6 &amp; 7: Open Reading Frames, Protein Search in NCBI database</title><link>https://rebelscience.club/2020/04/dna-toolkit-part-5-6-7-open-reading-frames-protein-search/</link><guid isPermaLink="true">https://rebelscience.club/2020/04/dna-toolkit-part-5-6-7-open-reading-frames-protein-search/</guid><pubDate>Sun, 26 Apr 2020 08:46:17 GMT</pubDate><description>In this article, we conclude our work on a minimal set of functions to work with DNA. We will add the last three functions that
</description><content:encoded><![CDATA[
<p class="wp-block-paragraph">In this article, we conclude our work on a minimal set of functions to work with DNA. We will add the last three functions that will help us to search for proteins in DNA sequences by generating reading frames. We will also apply our code to a real piece of genome that codes for Homo Sapiens Insult protein to see our code in action.</p>



<p class="wp-block-paragraph">Functions we will add:</p>



<ul class="wp-block-list"><li>Reading frame generation.</li><li>Protein Search in a reading frame (sub-function for the next function).</li><li>Protein search in all reading frames.</li></ul>



<p class="wp-block-paragraph">Let’s take a look at how codons (DNA nucleotides triplets) form a reading frame. We just scan a string of DNA, match every nucleotide triplet against a codon table, and in return, we get an amino acid. We keep accumulating amino acids to form an amino acid chain, also called a polypeptide chain. Here is a nice image that shows a reading frame:</p>



<figure class="wp-block-image alignwide size-large"><img decoding="async" src="https://www.genome.gov/sites/default/files/tg/en/illustration/open_reading_frame.jpg" alt=""/><figcaption>Source: <a href="https://www.genome.gov/genetics-glossary/Open-Reading-Frame">https://www.genome.gov/genetics-glossary/Open-Reading-Frame</a></figcaption></figure>



<p class="wp-block-paragraph">Also, here is a very nice explanation (audio) of what a reading frame is and why we need to form six of them for a proper protein search:</p>



<figure class="wp-block-audio aligncenter"><audio controls src="https://www.genome.gov/sites/default/files/tg/en/narration/open_reading_frame.mp3"></audio><figcaption>Source: <a rel="noreferrer noopener" href="https://www.genome.gov/genetics-glossary/Open-Reading-Frame" target="_blank">https://www.genome.gov/genetics-glossary/Open-Reading-Frame</a></figcaption></figure>



<p class="wp-block-paragraph">So let&#8217;s implement our reading frame generator to replicate the biological process that is performed by Ribisome in a living cell. We will reuse translation and reverse complement functions from our previous articles. In biology, Ribosome is an incredibly complex machine, but in the code, it is very simple:</p>


<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;monokai&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Python&quot;,&quot;language&quot;:&quot;Python&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;python&quot;}">def gen_reading_frames(seq):
    &quot;&quot;&quot;Generate the six reading frames of a DNA sequence&quot;&quot;&quot;
    &quot;&quot;&quot;including reverse complement&quot;&quot;&quot;
    
    frames = []
    frames.append(translate_seq(seq, 0))
    frames.append(translate_seq(seq, 1))
    frames.append(translate_seq(seq, 2))
    frames.append(translate_seq(reverse_complement(seq), 0))
    frames.append(translate_seq(reverse_complement(seq), 1))
    frames.append(translate_seq(reverse_complement(seq), 2))
    return frames</pre></div>


<ul class="wp-block-list"><li>We create a list to hold lists of amino acids. This list will hold six lists.</li><li>We add the first three reading frames, 5&#8242; to 3&#8242; end, by shifting one nucleotide in each frame. Our translation function accepts a string as a first argument and a start reading position as a second argument.</li><li>We do the same operation three more times, but we generate the reverse complement of our sequence first.</li></ul>



<p class="wp-block-paragraph">We can now add a 9th output to our <strong>main.py</strong> file. It is a loop in this case, as we need to print 6 lists.</p>


<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;monokai&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Python&quot;,&quot;language&quot;:&quot;Python&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;python&quot;}">print('[9] + Reading_frames:')
for frames in gen_reading_frames(DNAStr):
    print(frames)</pre></div>


<p class="wp-block-paragraph">If we now run this function on the string below, here is what we should see:</p>


<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;shell&quot;,&quot;mime&quot;:&quot;text/x-sh&quot;,&quot;theme&quot;:&quot;monokai&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Shell&quot;,&quot;language&quot;:&quot;Shell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;shell&quot;}">GGGCGGCTCG
['G', 'R', 'L']
['G', 'G', 'S']
['A', 'A']
['R', 'A', 'A']
['E', 'P', 'P']
['S', 'R']</pre></div>


<hr class="wp-block-separator"/>



<p class="wp-block-paragraph">The next function looks very convoluted, but it is very simple in principle. It uses an amino acid list as an argument and scans it to see if it contains a <strong>START</strong> &#8211; <strong>M</strong> codon and a <strong>STOP</strong> &#8211; <strong>_</strong> codon. When <strong>M</strong> codon is found (lines 13 &#8211; 16) we start accumulating every amino acid after that, until will come across a <strong>_</strong> codon (lines 7 &#8211; 11). We have two lists here: <strong>current_prot[]</strong> holds a current protein, being accumulated and <strong>proteins[]</strong> holds all found proteins in a sequence. This is needed because an amino acid sequence may contain multiple <strong>START</strong> &#8211; <strong>STOP</strong> codons, resulting in multiple possible proteins in a single sequence. Using a debugger to scan this function line by line will help to understand this code better. I also cover debugging this function in my video version of this article <a rel="noreferrer noopener" href="https://youtu.be/Vi9wv6b3deU?t=305" target="_blank">here</a>.</p>


<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;monokai&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Python&quot;,&quot;language&quot;:&quot;Python&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;python&quot;}">def proteins_from_rf(aa_seq):
    &quot;&quot;&quot;Compute all possible proteins in an aminoacid&quot;&quot;&quot;
    &quot;&quot;&quot;seq and return a list of possible proteins&quot;&quot;&quot;
    current_prot = []
    proteins = []
    for aa in aa_seq:
        if aa == &quot;_&quot;:
            # STOP accumulating amino acids if _ - STOP was found
            if current_prot:
                for p in current_prot:
                    proteins.append(p)
                current_prot = []
        else:
            # START accumulating amino acids if M - START was found
            if aa == &quot;M&quot;:
                current_prot.append(&quot;&quot;)
            for i in range(len(current_prot)):
                current_prot[i] += aa
    return proteins</pre></div>


<p class="wp-block-paragraph">In this case, we are not adding an output as this function is a sub-function for our next function, and it only builds a protein from a single reading frame. Our next function will use this code and pass all six reading frames to it.</p>



<p class="wp-block-paragraph">We can still do a quick test:</p>


<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;monokai&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Python&quot;,&quot;language&quot;:&quot;Python&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;python&quot;}">print(proteins_from_rf(['I', 'M', 'T', 'H', 'T',
                        'Q', 'G', 'N', 'V', 'A', 'Y', 'I', '_']))</pre></div>


<p class="wp-block-paragraph">And this protein sequence will be generated: <code>['MTHTQGNVAYI']</code></p>



<hr class="wp-block-separator"/>



<p class="wp-block-paragraph">Let&#8217;s now add our final function, that is a part of a pipeline. This function uses a few previous functions to generate a list of proteins for us, and it accepts 4 arguments; a sequence, a start reading and stop reading positions, and a boolean flag that lets us sort the list from a longest to a shortest protein sequence.</p>


<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;monokai&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Python&quot;,&quot;language&quot;:&quot;Python&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;python&quot;}">def all_proteins_from_orfs(seq, startReadPos=0, endReadPos=0, ordered=False):
    &quot;&quot;&quot;Compute all possible proteins for all open reading frames&quot;&quot;&quot;
    &quot;&quot;&quot;Protine Search DB: https://www.ncbi.nlm.nih.gov/nuccore/NM_001185097.2&quot;&quot;&quot;
    &quot;&quot;&quot;API can be used to pull protein info&quot;&quot;&quot;
    if endReadPos &gt; startReadPos:
        rfs = gen_reading_frames(seq[startReadPos: endReadPos])
    else:
        rfs = gen_reading_frames(seq)

    res = []
    for rf in rfs:
        prots = proteins_from_rf(rf)
        for p in prots:
            res.append(p)

    if ordered:
        return sorted(res, key=len, reverse=True)
    return res</pre></div>


<p class="wp-block-paragraph">We start by checking if the reading position was provided (lines 5 &#8211; 8). If yes, we generate reading frames for a slice of the string, if not, we generate reading frames for the whole sequence. This allows us to pass a sequence and just specify (if needed) a slice of it to look for proteins in, instead of pre-formatting (slicing) a string before providing it to our function.</p>



<p class="wp-block-paragraph">Lines 10 &#8211; 14 we scan all six reading frames and using our previous function to generate all possible proteins in a reading frame. We end up with a list <strong>res[]</strong> that contains all protein sequences, found in all six reading frames.</p>



<p class="wp-block-paragraph">I mentioned a pipeline above, as this function uses previous functions to produce the result. We start with a DNA sequence and we have this pipeline by using this function:<br><strong>DNA -> Translation -> Reverse Complement -> Reading Frame Generation -> Protein Assembly</strong></p>



<p class="wp-block-paragraph">Now let&#8217;s add our final, 10th output loop:</p>


<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;monokai&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Python&quot;,&quot;language&quot;:&quot;Python&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;python&quot;}">print('\n[10] + All prots in 6 open reading frames:')
for prot in all_proteins_from_orfs(DNAStr, 0, 0, True):
    print(f'{prot}')</pre></div>


<p class="wp-block-paragraph">The best way to test out the final function is to apply it to a real biological sequence. Homo sapiens insulin, variant 1. It can be found on NCBI database. If we look at a FASTA formatted file, we see this DNA sequence:</p>



<p class="wp-block-paragraph"><a href="https://www.ncbi.nlm.nih.gov/nuccore/NM_001185098.1?report=fasta" target="_blank" rel="noreferrer noopener">https://www.ncbi.nlm.nih.gov/nuccore/NM_001185098.1?report=fasta</a></p>



<p class="wp-block-paragraph">Let&#8217;s add it to our <strong>sequences.py </strong>file:</p>


<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;monokai&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Python&quot;,&quot;language&quot;:&quot;Python&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;python&quot;}"># NM_000207.3 Homo sapiens insulin (INS), transcript variant 1, mRNA
NM_000207_3 = '\
AGCCCTCCAGGACAGGCTGCATCAGAAGAGGCCATCAAGCAGATCACTGTCCTTCTGCCAT\
GGCCCTGTGGATGCGCCTCCTGCCCCTGCTGGCGCTGCTGGCCCTCTGGGGACCTGACCCA\
GCCGCAGCCTTTGTGAACCAACACCTGTGCGGCTCACACCTGGTGGAAGCTCTCTACCTAG\
TGTGCGGGGAACGAGGCTTCTTCTACACACCCAAGACCCGCCGGGAGGCAGAGGACCTGCA\
GGTGGGGCAGGTGGAGCTGGGCGGGGGCCCTGGTGCAGGCAGCCTGCAGCCCTTGGCCCTG\
GAGGGGTCCCTGCAGAAGCGTGGCATTGTGGAACAATGCTGTACCAGCATCTGCTCCCTCT\
ACCAGCTGGAGAACTACTGCAACTAGACGCAGCCCGCAGGCAGCCCCACACCCGCCGCCTC\
CTGCACCGAGAGAGATGGAATAAAGCCCTTGAACCAGC'</pre></div>


<p class="wp-block-paragraph">The main page shows a protein sequence we should get from that DNA sequence:</p>



<p class="wp-block-paragraph"><a href="https://www.ncbi.nlm.nih.gov/nuccore/NM_001185098.1" target="_blank" rel="noreferrer noopener">https://www.ncbi.nlm.nih.gov/nuccore/NM_001185098.1</a></p>



<p class="wp-block-paragraph"><code>/translation="MALWMRLLPLLALLALWGPDPAAAFVNQHLCGSHLVEALYLVCGERGFFYTPKTRREAEDLQVGQVELGGGPGAGSLQPLALEGSLQKRGIVEQCCTSICSLYQLENYCN"</code></p>



<p class="wp-block-paragraph">So let&#8217;s run our code and see if we can generate this protein:</p>


<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;monokai&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Python&quot;,&quot;language&quot;:&quot;Python&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;python&quot;}">print('\n[10] + All prots in 6 open reading frames:')
for prot in all_proteins_from_orfs(NM_000207_3, 0, 0, True):
    print(f'{prot}')</pre></div>


<p class="wp-block-paragraph">And here is what we see:</p>


<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/json&quot;,&quot;theme&quot;:&quot;monokai&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;full&quot;,&quot;fileName&quot;:&quot;JSON&quot;,&quot;language&quot;:&quot;JSON&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;json&quot;}">[10] + All prots in 6 open reading frames:
MALWMRLLPLLALLALWGPDPAAAFVNQHLCGSHLVEALYLVCGERGFFYTPKTRREAEDLQVGQVELGGGPGAGSLQPLALEGSLQKRGIVEQCCTSICSLYQLENYCN
MRLLPLLALLALWGPDPAAAFVNQHLCGSHLVEALYLVCGERGFFYTPKTRREAEDLQVGQVELGGGPGAGSLQPLALEGSLQKRGIVEQCCTSICSLYQLENYCN
MLVQHCSTMPRFCRDPSRAKGCRLPAPGPPPSSTCPTCRSSASRRVLGV
MPRFCRDPSRAKGCRLPAPGPPPSSTCPTCRSSASRRVLGV
MAEGQ
ME</pre></div>


<p class="wp-block-paragraph">We can see that the first protein in our output indeed matches NCBI proposed protein, confirming the correctness of our code in every step of the pipeline.</p>



<p class="wp-block-paragraph">Alright! This is it. Now we have a set of basic tools to work with DNA. Next, we will refactor this code into a nice reusable class and optimize some code. This might be overkill for an article, so if you are interested in wrapping this code into a class, feel free to watch parts 8 to 9, as they come out, here:</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Bioinformatics in Python: DNA Toolkit. Part 8.1: Code refactoring into a bio_seq class" width="640" height="360" src="https://www.youtube.com/embed/7HdmQ4AYjZw?list=PLpSOMAcxEB_hD18TAtBrTlRJDyu-PmRbj" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p class="wp-block-paragraph">GitHub repository: <a href="https://github.com/rebelC0der/DNA_Toolkit" target="_blank" rel="noreferrer noopener">https://github.com/rebelC0der/DNA_Toolkit</a></p>



<p class="wp-block-paragraph">Until next time, rebelCoder, signing out.</p>
]]></content:encoded></item></channel></rss>