<p>Actually the paper has made it clear how they did it. You just have to read the supplementary materials closer.</p>
<blockquote>
<p>In their figure from the paper: A is Red, C is Green, G is blue, and T
is Yellow (G+R), but this is still unclear how they the 3xNxN image.</p>
</blockquote>
<p>In RGB, each dimension is an NxN image. Since you have three dimensions, so it's 3xNxN. The red dimension was used to encode the nucleotide bases. The green dimension was used to encode quality scores. Finally, the blue dimension was used to encode the strand information.</p>
<blockquote>
<p>Obviously, DNA is a string over an alphabet with the characters: {A,
T, C, G}.</p>
</blockquote>
<p>This is easy. Lot's of ways. You could do a one-hot encoding or what DeepVariant used:</p>
<pre><code>def get_base_color(base):
    base_to_color = {'A': 250, 'G': 180, 'T': 100, 'C': 30}
    return base_to_color.get(base, 0)
</code></pre>

CC BY-SA 4.0
2020-08-26T00:03:53.703Z
2020-08-26T00:03:53.703Z
SmallChess
<p>Based on the <a href="https://www.biorxiv.org/content/biorxiv/suppl/2016/12/19/092890.DC2/092890-1.pdf" rel="nofollow noreferrer">supplementary material</a> as mentioned in a comment by Devon Ryan:</p>
<blockquote>
<p>The second phase of DeepVariant encodes the reference and read support
for each candidate variant into an RGB image. The pseudo-code for this
component is shown below; it contains all of the key operations to
build the image, leaving out for clarity error handling, code to deal
with edge cases like when variants occur close to the start or end of
the chromosome, and the implementation of non-essential and/or obvious
functions.</p>
</blockquote>
<p>Here is the main function:</p>
<pre class="lang-py prettyprint-override"><code>WIDTH = 221
HEIGHT = 100

def create_pileup_images(candidate_variants):
    for candidate in candidate_variants:
        for biallelic_variant in split_into_biallelics(candidate):
            start = biallelic_variant.start - (WIDTH - 1) / 2
            end = WIDTH - span_start
            ref_bases = reference.get_bases(start, end)
            image = Image(WIDTH, HEIGHT)
            row_i = fill_reference_pixels(ref_bases, image)
            for read in reads.get_overlapping(start, end):
                if row_i &lt; HEIGHT and is_usable_read(read):
                    add_read(image, read, row_i)
                    row_i += 1
            yield image

def fill_reference_pixels(ref, image):
    for row in range(5):
        for col in range(WIDTH):
            alpha = 0.4
            ref_base = ref[col]
            red = get_base_color(ref_base)
            green = get_quality_color(60)  # The reference is high quality
            blue = get_strand_color(True)  # The reference is on the positive strand
            image[row, col] = make_pixel(red, green, blue, alpha)
    return 5

</code></pre>

CC BY-SA 4.0
2020-08-23T15:48:37.587Z
2024-06-14T04:49:07.820Z
2024-06-14T04:49:07.820Z
0x90
<p><a href="https://github.com/google/deepvariant/" rel="nofollow noreferrer">DeepVariant</a> is a pipeline to call genetic variants from DNA sequencing data.</p>
<p>A major step, before feeding the CNN, is to translate these DNA sequences into images. It's unclear why and how Google <a href="https://www.biorxiv.org/content/10.1101/092890v6" rel="nofollow noreferrer">constructs the RGB images</a> from the DNA data. Obviously, DNA is a string over an alphabet with the characters: {A, T, C, G}.</p>
<p>It is even hard to understand how the <a href="http://ai.googleblog.com/2017/12/deepvariant-highly-accurate-genomes.html" rel="nofollow noreferrer">mapping</a> works based on the source code of their <a href="https://github.com/google/deepvariant/blob/r0.10/deepvariant/pileup_image_test.py" rel="nofollow noreferrer">unit tests</a>.</p>
<p>In their figure from the paper: A is Red, C is Green, G is blue, and T is Yellow (G+R), but this is still unclear how they construct the <code>3xNxN</code> image.</p>
<p><a href="https://i.sstatic.net/d9NPSm.pnge" rel="nofollow noreferrer"><img src="https://i.sstatic.net/d9NPSm.pnge" alt="enter image description here" /></a></p>
<hr />
<p>EDIT from <a href="https://google.github.io/deepvariant/posts/2020-02-20-looking-through-deepvariants-eyes/" rel="nofollow noreferrer">google's blog</a>:</p>
<blockquote>
<p>In this article we will show the six channels in a row, but in
DeepVariant they are encoded as six layers in the third dimension,
giving each tensor a shape of (100, 221, 6) corresponding to (height,
width, channels). The variant in question is always in the center of
each pileup image, here marked with a small line at the top.</p>
<p>Channels are shown in greyscale below in the following order:</p>
<p>Read base: different intensities represent A, C, G, and T.</p>
<p>Base quality: set by the sequencing machine. White is higher quality.</p>
<p>Mapping quality: set by the aligner. White is higher quality.</p>
<p>Strand of alignment: Black is forward; white is reverse.</p>
<p>Read supports variant: White means the read supports the given
alternate allele, grey means it does not.</p>
<p>Base differs from ref: White means the base is different from the
reference, dark grey means the base matches the reference.</p>
</blockquote>
<p><a href="https://i.sstatic.net/MoGCs.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/MoGCs.png" alt="enter image description here" /></a></p>

CC BY-SA 4.0
2020-08-20T21:50:14.350Z
See page 3 of https://www.biorxiv.org/content/biorxiv/suppl/2016/12/19/092890.DC2/092890-1.pdf
Devon Ryan
<python><variant-calling><machine-learning><deep-learning>
How does DeepVariant construct RGB images from DNA sequences?
# How does DeepVariant construct RGB images from DNA sequences?

(Asked by: username_0 on 2020-08-19)

[DeepVariant](https://github.com/google/deepvariant/) is a pipeline to call genetic variants from DNA sequencing data.

A major step, before feeding the CNN, is to translate these DNA sequences into images. It's unclear why and how Google [constructs the RGB images](https://www.biorxiv.org/content/10.1101/092890v6) from the DNA data. Obviously, DNA is a string over an alphabet with the characters: {A, T, C, G}.

It is even hard to understand how the [mapping](http://ai.googleblog.com/2017/12/deepvariant-highly-accurate-genomes.html) works based on the source code of their [unit tests](https://github.com/google/deepvariant/blob/r0.10/deepvariant/pileup_image_test.py).

In their figure from the paper: A is Red, C is Green, G is blue, and T is Yellow (G+R), but this is still unclear how they construct the `3xNxN` image.

[![enter image description here](https://i.sstatic.net/d9NPSm.pnge)](https://i.sstatic.net/d9NPSm.pnge)

---

EDIT from [google's blog](https://google.github.io/deepvariant/posts/2020-02-20-looking-through-deepvariants-eyes/):

> In this article we will show the six channels in a row, but in
> DeepVariant they are encoded as six layers in the third dimension,
> giving each tensor a shape of (100, 221, 6) corresponding to (height,
> width, channels). The variant in question is always in the center of
> each pileup image, here marked with a small line at the top.
>
> Channels are shown in greyscale below in the following order:
>
> Read base: different intensities represent A, C, G, and T.
>
> Base quality: set by the sequencing machine. White is higher quality.
>
> Mapping quality: set by the aligner. White is higher quality.
>
> Strand of alignment: Black is forward; white is reverse.
>
> Read supports variant: White means the read supports the given
> alternate allele, grey means it does not.
>
> Base differs from ref: White means the base is different from the
> reference, dark grey means the base matches the reference.

[![enter image description here](https://i.sstatic.net/MoGCs.png)](https://i.sstatic.net/MoGCs.png)

**Tags:** python, variant-calling, machine-learning, deep-learning
> **Comments:**
> **username_1**: See page 3 of https://www.biorxiv.org/content/biorxiv/suppl/2016/12/19/092890.DC2/092890-1.pdf  

---

## 2 answers

### Answer by username_2 on 2020-08-26. Score: 2 | Accepted answer

Actually the paper has made it clear how they did it. You just have to read the supplementary materials closer.

In their figure from the paper: A is Red, C is Green, G is blue, and T
is Yellow (G+R), but this is still unclear how they the 3xNxN image.

In RGB, each dimension is an NxN image. Since you have three dimensions, so it's 3xNxN. The red dimension was used to encode the nucleotide bases. The green dimension was used to encode quality scores. Finally, the blue dimension was used to encode the strand information.

Obviously, DNA is a string over an alphabet with the characters: {A,
T, C, G}.

This is easy. Lot's of ways. You could do a one-hot encoding or what DeepVariant used:
def get_base_color(base):
    base_to_color = {'A': 250, 'G': 180, 'T': 100, 'C': 30}
    return base_to_color.get(base, 0)


---

### Answer by username_0 on 2020-08-23. Score: 1

Based on the supplementary material as mentioned in a comment by Devon Ryan:

The second phase of DeepVariant encodes the reference and read support
for each candidate variant into an RGB image. The pseudo-code for this
component is shown below; it contains all of the key operations to
build the image, leaving out for clarity error handling, code to deal
with edge cases like when variants occur close to the start or end of
the chromosome, and the implementation of non-essential and/or obvious
functions.

Here is the main function:
WIDTH = 221
HEIGHT = 100

def create_pileup_images(candidate_variants):
    for candidate in candidate_variants:
        for biallelic_variant in split_into_biallelics(candidate):
            start = biallelic_variant.start - (WIDTH - 1) / 2
            end = WIDTH - span_start
            ref_bases = reference.get_bases(start, end)
            image = Image(WIDTH, HEIGHT)
            row_i = fill_reference_pixels(ref_bases, image)
            for read in reads.get_overlapping(start, end):
                if row_i < HEIGHT and is_usable_read(read):
                    add_read(image, read, row_i)
                    row_i += 1
            yield image

def fill_reference_pixels(ref, image):
    for row in range(5):
        for col in range(WIDTH):
            alpha = 0.4
            ref_base = ref[col]
            red = get_base_color(ref_base)
            green = get_quality_color(60)  # The reference is high quality
            blue = get_strand_color(True)  # The reference is on the positive strand
            image[row, col] = make_pixel(red, green, blue, alpha)
    return 5


---

