about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--gn3/api/gemma.py19
-rw-r--r--gn3/computations/gemma.py14
-rw-r--r--tests/integration/test_gemma.py69
-rw-r--r--tests/unit/computations/test_gemma.py1
4 files changed, 83 insertions, 20 deletions
diff --git a/gn3/api/gemma.py b/gn3/api/gemma.py
index effae8a..7c76f2f 100644
--- a/gn3/api/gemma.py
+++ b/gn3/api/gemma.py
@@ -35,10 +35,12 @@ file output is returned.
     """
     data = request.get_json()
     app_defaults = current_app.config.get('APP_DEFAULTS')
-    __hash = generate_hash_of_string("".join(data.get("values")))
+    __hash = generate_hash_of_string(
+        f"{data.get('genofile_name')}_"
+        ''.join(data.get("values", "")))
     gemma_kwargs = {
         "geno_filename": os.path.join(app_defaults.get("GENODIR"), "bimbam",
-                                      f"{data.get('genofile_name')}.txt"),
+                                      f"{data.get('geno_filename')}"),
         "trait_filename": generate_pheno_txt_file(
             tmpdir=app_defaults.get("TMPDIR"),
             values=data.get("values"),
@@ -46,18 +48,21 @@ file output is returned.
             trait_filename=(f"{data.get('dataset_groupname')}_"
                             f"{data.get('trait_name')}_"
                             f"{__hash}.txt"))}
+    gemma_wrapper_kwargs = {}
+    if data.get("loco"):
+        gemma_wrapper_kwargs["loco"] = f"--input {data.get('loco')}"
     k_computation_cmd = generate_gemma_computation_cmd(
-        gemma_cmd=app_defaults.get("GEMMA_WRAPPER_CMD"),
+        gemma_cmd=app_defaults.get("GEMMA_WRAPPER_CMD") + "_haha",
+        gemma_wrapper_kwargs={"loco": f"--input {data.get('loco')}"},
         gemma_kwargs=gemma_kwargs,
         output_file=(f"{app_defaults.get('TMPDIR')}/gn2/"
                      f"{data.get('dataset_name')}_K_"
                      f"{__hash}.json"))
-    if data.get("covariates"):
-        gemma_kwargs["c"] = os.path.join(app_defaults.get("GENODIR"),
-                                         "bimbam",
-                                         data.get("covariates"))
     gemma_kwargs["lmm"] = data.get("lmm", 9)
+    gemma_wrapper_kwargs["input"] = (f"{data.get('dataset_name')}_K_"
+                                     f"{__hash}.json")
     gwa_cmd = generate_gemma_computation_cmd(
+        gemma_wrapper_kwargs=gemma_wrapper_kwargs,
         gemma_cmd=app_defaults.get("GEMMA_WRAPPER_CMD"),
         gemma_kwargs=gemma_kwargs,
         output_file=(f"{data.get('dataset_name')}_GWA_"
diff --git a/gn3/computations/gemma.py b/gn3/computations/gemma.py
index 5741692..528f888 100644
--- a/gn3/computations/gemma.py
+++ b/gn3/computations/gemma.py
@@ -55,10 +55,12 @@ def do_paths_exist(paths: ValuesView) -> bool:
     return True
 
 
-def generate_gemma_computation_cmd(gemma_cmd: str,
-                                   gemma_kwargs: Dict[str, str],
-                                   output_file: str) -> Optional[str]:
-    """Create a higher order function that generates a command"""
+def generate_gemma_computation_cmd(
+        gemma_cmd: str,
+        gemma_kwargs: Dict[str, str],
+        output_file: str,
+        gemma_wrapper_kwargs: Dict[str, str]) -> Optional[str]:
+    """Create a computation cmd"""
     geno_filename = gemma_kwargs.get("geno_filename", "")
     trait_filename = gemma_kwargs.get("trait_filename")
     ext, snps_filename = geno_filename.partition(".")[-1], ""
@@ -66,13 +68,13 @@ def generate_gemma_computation_cmd(gemma_cmd: str,
         snps_filename = geno_filename.replace(f".{ext}", "")
         snps_filename += f"_snps.{ext}"
     _kwargs = {"g": geno_filename, "p": trait_filename}
-    if gemma_kwargs.get("covar_filename"):
-        _kwargs["a"] = gemma_kwargs.get("covar_filename")
+    _kwargs["a"] = snps_filename
     if not do_paths_exist(_kwargs.values()):  # Prevents injection!
         return None
     if _kwargs.get("lmm"):
         _kwargs["lmm"] = gemma_kwargs.get("lmm")
     return compose_gemma_cmd(gemma_wrapper_cmd=gemma_cmd,
+                             gemma_wrapper_kwargs=gemma_wrapper_kwargs,
                              gemma_kwargs=_kwargs,
                              gemma_args=["-gk", ">",
                                          output_file])
diff --git a/tests/integration/test_gemma.py b/tests/integration/test_gemma.py
index 598c91f..1f59530 100644
--- a/tests/integration/test_gemma.py
+++ b/tests/integration/test_gemma.py
@@ -1,4 +1,5 @@
 """Integration tests for gemma API endpoints"""
+import os
 import unittest
 
 from dataclasses import dataclass
@@ -17,7 +18,14 @@ class MockRedis:
 class GemmaAPITest(unittest.TestCase):
     """Test cases for the Gemma API"""
     def setUp(self):
-        self.app = create_app().test_client()
+        self.app = create_app({
+            "APP_DEFAULTS": {
+                "GENODIR": os.path.abspath(
+                    os.path.join(os.path.dirname(__file__),
+                                 "test_data/")),
+                "TMPDIR": "/tmp",
+                "REDIS_JOB_QUEUE": "GN3::job-queue",
+                "GEMMA_WRAPPER_CMD": "gemma-wrapper"}}).test_client()
 
     @mock.patch("gn3.api.gemma.run_cmd")
     def test_get_version(self, mock_run_cmd):
@@ -31,9 +39,9 @@ class GemmaAPITest(unittest.TestCase):
     @mock.patch("gn3.api.gemma.redis.Redis")
     @mock.patch("gn3.api.gemma.queue_cmd")
     @mock.patch("gn3.api.gemma.generate_gemma_computation_cmd")
-    def test_run_gemma(self, mock_gemma_computation_cmd,
-                       mock_queue_cmd, mock_redis):
-        """Test that gemma composes the command correctly"""
+    def test_run_gemma_no_loco(self, mock_gemma_computation_cmd,
+                               mock_queue_cmd, mock_redis):
+        """Test that gemma composes the command correctly without loco"""
         _redis_conn = MockRedis(redis=mock.MagicMock(), hget=mock.MagicMock())
         mock_redis.return_value = _redis_conn
         mock_gemma_computation_cmd.side_effect = [
@@ -42,7 +50,9 @@ class GemmaAPITest(unittest.TestCase):
              "test.txt -a genofile_snps.txt "
              "-gk > /tmp/gn2/"
              "bxd_K_gUFhGu4rLG7k+CXLPk1OUg.txt"),
-            ("gemma-wrapper --json -- "
+            ("gemma-wrapper --json --input /tmp/gn2/"
+             "bxd_K_gUFhGu4rLG7k+CXLPk1OUg.txt -- "
+             "-a genofile_snps.txt -lmm 9 "
              "-g genofile.txt -p "
              "test.txt -a genofile_snps.txt "
              "-gk > /tmp/gn2/"
@@ -66,7 +76,9 @@ class GemmaAPITest(unittest.TestCase):
                             "genofile.txt -p test.txt "
                             "-a genofile_snps.txt -gk > "
                             "/tmp/gn2/bxd_K_gUFhGu4rLG7k+CXLPk1OUg.txt "
-                            "&& gemma-wrapper --json -- -g "
+                            "&& gemma-wrapper --json --input "
+                            "/tmp/gn2/bxd_K_gUFhGu4rLG7k+CXLPk1OUg.txt"
+                            " -- -a genofile_snps.txt -lmm 9 -g "
                             "genofile.txt -p test.txt "
                             "-a genofile_snps.txt "
                             "-gk > "
@@ -78,7 +90,50 @@ class GemmaAPITest(unittest.TestCase):
             response.get_json(),
             {"unique_id": 'my-unique-id',
              "status": "queued",
-             "output_file": "BXD_GWA_9lo8zwOOXbfB73EcyXxAYQ.txt"})
+             "output_file": "BXD_GWA_WzxVcfhKAn4fJnSWpsBq0g.txt"})
+
+    @mock.patch("gn3.api.gemma.redis.Redis")
+    @mock.patch("gn3.api.gemma.queue_cmd")
+    def test_run_gemma_with_loco(self,
+                                 mock_queue_cmd, mock_redis):
+        """Test that gemma composes the command correctly with loco"""
+        _redis_conn = MockRedis(redis=mock.MagicMock(), hget=mock.MagicMock())
+        mock_redis.return_value = _redis_conn
+        mock_queue_cmd.return_value = "my-unique-id"
+        response = self.app.post("/gemma/k-gwa-computation", json={
+            "trait_filename": os.path.abspath(os.path.join(
+                os.path.dirname(__file__),
+                "test_data/"
+            )),
+            "geno_filename": "BXD_geno.txt.gz",
+            "values": ["X", "N/A", "X"],
+            "dataset_groupname": "BXD",
+            "trait_name": "Height",
+            "email": "me@me.com",
+            "dataset_name": "BXD",
+            "loco": "1,2,3,4,5,6"
+        })
+        mock_queue_cmd.called_with(
+            conn=_redis_conn,
+            email="me@me.com",
+            job_queue="GN3::job-queue",
+            cmd=("gemma-wrapper --json -- -g "
+                 "genofile.txt -p test.txt "
+                 "-a genofile_snps.txt -gk > "
+                 "/tmp/gn2/bxd_K_gUFhGu4rLG7k+CXLPk1OUg.txt "
+                 "&& gemma-wrapper --json --input "
+                 "/tmp/gn2/bxd_K_gUFhGu4rLG7k+CXLPk1OUg.txt"
+                 " -- -a genofile_snps.txt -lmm 9 -g "
+                 "genofile.txt -p test.txt "
+                 "-a genofile_snps.txt "
+                 "-gk > "
+                 "/tmp/gn2/"
+                 "bxd_GWA_gUFhGu4rLG7k+CXLPk1OUg.txt"))
+        self.assertEqual(
+            response.get_json(),
+            {"unique_id": 'my-unique-id',
+             "status": "queued",
+             "output_file": "BXD_GWA_WzxVcfhKAn4fJnSWpsBq0g.txt"})
 
     @mock.patch("gn3.api.gemma.redis.Redis")
     def test_check_cmd_status(self, mock_redis):
diff --git a/tests/unit/computations/test_gemma.py b/tests/unit/computations/test_gemma.py
index a7884ea..b5ffbfd 100644
--- a/tests/unit/computations/test_gemma.py
+++ b/tests/unit/computations/test_gemma.py
@@ -38,6 +38,7 @@ class TestGemma(unittest.TestCase):
         self.assertEqual(
             generate_gemma_computation_cmd(
                 gemma_cmd="gemma-wrapper",
+                gemma_wrapper_kwargs=None,
                 gemma_kwargs={
                     "geno_filename": "genofile.txt",
                     "trait_filename": "test.txt",