aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gn3/computations/heatmap.py7
-rw-r--r--gn3/computations/qtlreaper.py27
-rw-r--r--gn3/db/traits.py5
-rw-r--r--gn3/heatmaps/heatmaps.py25
-rw-r--r--gn3/random.py11
-rw-r--r--tests/unit/computations/test_qtlreaper.py5
6 files changed, 55 insertions, 25 deletions
diff --git a/gn3/computations/heatmap.py b/gn3/computations/heatmap.py
index 92014cf..1143450 100644
--- a/gn3/computations/heatmap.py
+++ b/gn3/computations/heatmap.py
@@ -6,6 +6,7 @@ generate various kinds of heatmaps.
from functools import reduce
from typing import Any, Dict, Sequence
from gn3.computations.slink import slink
+from gn3.computations.qtlreaper import generate_traits_file
from gn3.computations.correlations2 import compute_correlation
from gn3.db.genotypes import build_genotype_file, load_genotype_samples
from gn3.db.traits import (
@@ -155,14 +156,14 @@ def heatmap_data(traits_names, conn: Any):
for fullname in traits_names]
traits_list = tuple(x[0] for x in traits_details)
traits_data_list = [x[1] for x in traits_details]
- exported_traits_data_list = tuple(
- export_trait_data(td, strainlist) for td in traits_data_list)
genotype_filename = build_genotype_file(traits_list[0]["riset"])
strainlist = load_genotype_samples(genotype_filename)
+ exported_traits_data_list = tuple(
+ export_trait_data(td, strainlist) for td in traits_data_list)
slink_data = slink(cluster_traits(exported_traits_data_list))
ordering_data = compute_heatmap_order(slink_data)
strains_and_values = retrieve_strains_and_values(
- orders, strainlist, exported_traits_data_list)
+ ordering_data, strainlist, exported_traits_data_list)
strains_values = strains_and_values[0][1]
trait_values = [t[2] for t in strains_and_values]
traits_filename = generate_traits_filename()
diff --git a/gn3/computations/qtlreaper.py b/gn3/computations/qtlreaper.py
index 3b8e4db..30c7051 100644
--- a/gn3/computations/qtlreaper.py
+++ b/gn3/computations/qtlreaper.py
@@ -3,17 +3,10 @@ This module contains functions to interact with the `qtlreaper` utility for
computation of QTLs.
"""
import os
-import random
-import string
import subprocess
+from gn3.random import random_string
from gn3.settings import TMPDIR, REAPER_COMMAND
-def random_string(length):
- """Generate a random string of length `length`."""
- return "".join(
- random.choices(
- string.ascii_letters + string.digits, k=length))
-
def generate_traits_file(strains, trait_values, traits_filename):
"""
Generate a traits file for use with `qtlreaper`.
@@ -25,11 +18,13 @@ def generate_traits_file(strains, trait_values, traits_filename):
computation of QTLs.
"""
header = "Trait\t{}\n".format("\t".join(strains))
- data = [header] + [
- "T{}\t{}\n".format(i+1, "\t".join([str(i) for i in t]))
- for i, t in enumerate(trait_values[:-1])] + [
- "T{}\t{}".format(len(trait_values), "\t".join([str(i) for i in t]))
- for t in trait_values[-1:]]
+ data = (
+ [header] +
+ ["T{}\t{}\n".format(i+1, "\t".join([str(i) for i in t]))
+ for i, t in enumerate(trait_values[:-1])] +
+ ["T{}\t{}".format(
+ len(trait_values), "\t".join([str(i) for i in t]))
+ for t in trait_values[-1:]])
with open(traits_filename, "w") as outfile:
outfile.writelines(data)
@@ -93,6 +88,9 @@ def run_reaper(
def parse_reaper_main_results(results_file):
+ """
+ Parse the results file of running QTLReaper into a list of dicts.
+ """
with open(results_file, "r") as infile:
lines = infile.readlines()
@@ -104,6 +102,9 @@ def parse_reaper_main_results(results_file):
return [dict(zip(header, __parse_line(line))) for line in lines[1:]]
def parse_reaper_permutation_results(results_file):
+ """
+ Parse the results QTLReaper permutations into a list of values.
+ """
with open(results_file, "r") as infile:
lines = infile.readlines()
diff --git a/gn3/db/traits.py b/gn3/db/traits.py
index ccb101a..bfe887e 100644
--- a/gn3/db/traits.py
+++ b/gn3/db/traits.py
@@ -1,6 +1,8 @@
"""This class contains functions relating to trait data manipulation"""
-from gn3.settings import TMPDIR
+import os
from typing import Any, Dict, Union, Sequence
+from gn3.settings import TMPDIR
+from gn3.random import random_string
from gn3.function_helpers import compose
from gn3.db.datasets import retrieve_trait_dataset
@@ -669,5 +671,6 @@ def retrieve_trait_data(trait: dict, conn: Any, strainlist: Sequence[str] = tupl
return {}
def generate_traits_filename(base_path: str = TMPDIR):
+ """Generate a unique filename for use with generated traits files."""
return "{}/traits_test_file_{}.txt".format(
os.path.abspath(base_path), random_string(10))
diff --git a/gn3/heatmaps/heatmaps.py b/gn3/heatmaps/heatmaps.py
index 3bf7917..88f546d 100644
--- a/gn3/heatmaps/heatmaps.py
+++ b/gn3/heatmaps/heatmaps.py
@@ -14,6 +14,19 @@ def generate_random_data(data_stop: float = 2, width: int = 10, height: int = 30
return [[random.uniform(0,data_stop) for i in range(0, width)]
for j in range(0, height)]
+def generate_random_data2(data_stop: float = 2, width: int = 10, height: int = 30):
+ """
+ This is mostly a utility function to be used to generate random data, useful
+ for development of the heatmap generation code, without access to the actual
+ database data.
+ """
+ return [
+ [{
+ "value": item,
+ "category": random.choice(["C57BL/6J +", "DBA/2J +"])}
+ for item in axis]
+ for axis in generate_random_data(data_stop, width, height)]
+
def heatmap_x_axis_names():
return [
"UCLA_BXDBXH_CARTILAGE_V2::ILM103710672",
@@ -30,13 +43,14 @@ def heatmap_x_axis_names():
# Grey + Blue + Red
def generate_heatmap():
- rows = 20
- data = generate_random_data(height=rows)
- y = (["%s"%x for x in range(1, rows+1)][:-1] + ["X"]) #replace last item with x for now
+ cols = 20
+ y_axis = (["%s"%x for x in range(1, cols+1)][:-1] + ["X"]) #replace last item with x for now
+ x_axis = heatmap_x_axis_names()
+ data = generate_random_data(height=cols, width=len(x_axis))
fig = px.imshow(
data,
- x=heatmap_x_axis_names(),
- y=y,
+ x=x_axis,
+ y=y_axis,
width=500)
fig.update_traces(xtype="array")
fig.update_traces(ytype="array")
@@ -49,6 +63,5 @@ def generate_heatmap():
coloraxis_colorscale=[
[0.0, '#3B3B3B'], [0.4999999999999999, '#ABABAB'],
[0.5, '#F5DE11'], [1.0, '#FF0D00']])
-
fig.write_html("%s/%s"%(heatmap_dir, "test_image.html"))
return fig
diff --git a/gn3/random.py b/gn3/random.py
new file mode 100644
index 0000000..f0ba574
--- /dev/null
+++ b/gn3/random.py
@@ -0,0 +1,11 @@
+"""
+Functions to generate complex random data.
+"""
+import random
+import string
+
+def random_string(length):
+ """Generate a random string of length `length`."""
+ return "".join(
+ random.choices(
+ string.ascii_letters + string.digits, k=length))
diff --git a/tests/unit/computations/test_qtlreaper.py b/tests/unit/computations/test_qtlreaper.py
index ec23664..6c3b64d 100644
--- a/tests/unit/computations/test_qtlreaper.py
+++ b/tests/unit/computations/test_qtlreaper.py
@@ -1,5 +1,4 @@
"""Module contains tests for gn3.computations.qtlreaper"""
-import os
from unittest import TestCase
from gn3.computations.qtlreaper import (
parse_reaper_main_results, parse_reaper_permutation_results)
@@ -8,6 +7,7 @@ class TestQTLReaper(TestCase):
"""Class for testing qtlreaper interface functions."""
def test_parse_reaper_main_results(self):
+ """Test that the main results file is parsed correctly."""
self.assertEqual(
parse_reaper_main_results(
"tests/unit/computations/data/qtlreaper/main_output_sample.txt"),
@@ -65,9 +65,10 @@ class TestQTLReaper(TestCase):
])
def test_parse_reaper_permutation_results(self):
+ """Test that the permutations results file is parsed correctly."""
self.assertEqual(
parse_reaper_permutation_results(
- "tests/unit/computations/data/qtlreaper/permu_output_sample.txt"),
+ "tests/unit/computations/data/qtlreaper/permu_output_sample.txt"),
[4.44174, 5.03825, 5.08167, 5.18119, 5.18578, 5.24563, 5.24619,
5.24619, 5.27961, 5.28228, 5.43903, 5.50188, 5.51694, 5.56830,
5.63874, 5.71346, 5.71936, 5.74275, 5.76764, 5.79815, 5.81671,