Repository: lifeomic/phc-sdk-py

Issue:
Add variant_set_id when returning GenomicShortVariant
The id of the variants comes in the following form:
```python
'55e945ec-57d1-4dde-9a59-bcdd6d7271e6:+0LLoDMx2dXBmvef9GcN4Dz+v4EMI87/FXW9X2mG72k=:TFB2M'
```

The first part of this ID is the variant_set_id which can be joined with the output of the `GenomicTest` to match a given mutation to the patient. This is a common use case.



Comments:

Patch:
diff --git a/phc/easy/__init__.py b/phc/easy/__init__.py
index db31100..b50bf0c 100644
--- a/phc/easy/__init__.py
+++ b/phc/easy/__init__.py
@@ -8,8 +8,6 @@ from phc.easy.diagnostic_report import DiagnosticReport
 from phc.easy.document_reference import DocumentReference
 from phc.easy.encounter import Encounter
 from phc.easy.frame import Frame
-from phc.easy.genomic_short_variant import GenomicShortVariant
-from phc.easy.genomic_test import GenomicTest
 from phc.easy.goal import Goal
 from phc.easy.imaging_study import ImagingStudy
 from phc.easy.immunization import Immunization
@@ -20,6 +18,8 @@ from phc.easy.medication_dispense import MedicationDispense
 from phc.easy.medication_request import MedicationRequest
 from phc.easy.medication_statement import MedicationStatement
 from phc.easy.observation import Observation
+from phc.easy.omics.genomic_short_variant import GenomicShortVariant
+from phc.easy.omics.genomic_test import GenomicTest
 from phc.easy.organization import Organization
 from phc.easy.patient_item import PatientItem
 from phc.easy.patients import Patient
@@ -34,7 +34,6 @@ from phc.easy.referral_request import ReferralRequest
 from phc.easy.sequence import Sequence
 from phc.easy.specimen import Specimen
 
-
 __all__ = [
     "AuditEvent",
     "Auth",
diff --git a/phc/easy/omics/__init__.py b/phc/easy/omics/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/phc/easy/omics/genomic_short_variant.py b/phc/easy/omics/genomic_short_variant.py
new file mode 100644
index 0000000..c2f69cc
--- /dev/null
+++ b/phc/easy/omics/genomic_short_variant.py
@@ -0,0 +1,125 @@
+import inspect
+from typing import List, Optional
+
+import pandas as pd
+from phc.easy.auth import Auth
+from phc.easy.frame import Frame
+from phc.easy.omics.options.genomic_short_variant import (
+    GenomicShortVariantInclude,
+    GenomicShortVariantOptions,
+)
+from phc.easy.paging_api_item import PagingApiItem
+
+
+class GenomicShortVariant(PagingApiItem):
+    @staticmethod
+    def resource_path():
+        return "genomics/variants"
+
+    @staticmethod
+    def params_class():
+        return GenomicShortVariantOptions
+
+    @staticmethod
+    def transform_results(data_frame: pd.DataFrame, **expand_args):
+        def expand_id(id_column: pd.Series):
+            return pd.concat(
+                [
+                    id_column,
+                    id_column.str.split(":", expand=True).rename(
+                        columns={0: "variant_set_id", 2: "gene"}
+                    )[["variant_set_id", "gene"]],
+                ],
+                axis=1,
+            )
+
+        args = {
+            **expand_args,
+            "custom_columns": [
+                *expand_args.get("custom_columns", []),
+                *[
+                    Frame.codeable_like_column_expander(k)
+                    for k in ["clinvar", "cosmic", "vcf"]
+                ],
+                ("id", expand_id),
+            ],
+        }
+
+        return Frame.expand(data_frame, **args)
+
+    @classmethod
+    def get_data_frame(
+        cls,
+        # Query parameters
+        variant_set_ids: List[str],
+        include: List[GenomicShortVariantInclude] = ["vcf"],
+        gene: List[str] = [],
+        rsid: List[str] = [],
+        chromosome: List[str] = [],
+        clinvar_allele_id: List[str] = [],
+        clinvar_disease: List[str] = [],
+        clinvar_review: List[str] = [],
+        clinvar_significance: List[str] = [],
+        cosmic_id: List[str] = [],
+        cosmic_status: List[str] = [],
+        cosmic_histology: List[str] = [],
+        cosmic_tumor_site: List[str] = [],
+        variant_class: List[str] = [],
+        group: List[str] = [],
+        impact: List[str] = [],
+        transcript_id: List[str] = [],
+        biotype: List[str] = [],
+        amino_acid_change: List[str] = [],
+        sequence_type: List[str] = [],
+        position: List[str] = [],
+        cosmic_sample_count: List[str] = [],
+        min_allele_frequency: List[str] = [],
+        max_allele_frequency: List[str] = [],
+        pop_allele_frequency: List[str] = [],
+        exac_allele_frequency: List[str] = [],
+        exac_homozygous: List[str] = [],
+        dbnsfp_damaging_count: List[str] = [],
+        dbnsfp_damaging_predictor: List[str] = [],
+        dbnsfp_damaging_vote: List[str] = [],
+        dbnsfp_fathmm_rankscore: List[str] = [],
+        dbnsfp_fathmm_pred: List[str] = [],
+        dbnsfp_mean_rankscore: List[str] = [],
+        dbnsfp_mean_rankscore_predictor: List[str] = [],
+        dbnsfp_mutationtaster_rankscore: List[str] = [],
+        dbnsfp_mutationtaster_pred: List[str] = [],
+        dbnsfp_sift_rankscore: List[str] = [],
+        dbnsfp_sift_pred: List[str] = [],
+        zygosity: List[str] = [],
+        genotype: List[str] = [],
+        variant_allele_frequency: List[str] = [],
+        quality: List[str] = [],
+        read_depth: List[str] = [],
+        alt_read_depth: List[str] = [],
+        ref_read_depth: List[str] = [],
+        variant_filter: List[str] = [],
+        drug_associations: Optional[bool] = None,
+        # Execution parameters,
+        all_results: bool = False,
+        auth_args: Auth = Auth.shared(),
+        max_pages: Optional[int] = None,
+        page_size: Optional[int] = None,
+        log: bool = False,
+        **kw_args,
+    ):
+        """Execute a request for genomic short variants
+
+        ## Parameters
+
+        Query: `phc.easy.omics.options.genomic_short_variant.GenomicShortVariantOptions`
+
+        Execution: `phc.easy.query.Query.execute_paging_api`
+
+        Expansion: `phc.easy.frame.Frame.expand`
+
+        NOTE:
+         - `variant_class` is translated to `class` as a parameter
+         - `variant_filter` is translated to `filter` as a parameter
+        """
+        return super().get_data_frame(
+            **kw_args, **cls._get_current_args(inspect.currentframe(), locals())
+        )
diff --git a/phc/easy/genomic_test.py b/phc/easy/omics/genomic_test.py
similarity index 100%
rename from phc/easy/genomic_test.py
rename to phc/easy/omics/genomic_test.py
diff --git a/phc/easy/omics/options/__init__.py b/phc/easy/omics/options/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/phc/easy/genomic_short_variant.py b/phc/easy/omics/options/genomic_short_variant.py
similarity index 52%
rename from phc/easy/genomic_short_variant.py
rename to phc/easy/omics/options/genomic_short_variant.py
index f6aa6db..22ed728 100644
--- a/phc/easy/genomic_short_variant.py
+++ b/phc/easy/omics/options/genomic_short_variant.py
@@ -1,13 +1,8 @@
-import inspect
-import pandas as pd
-from typing import List, Optional
-from phc.easy.frame import Frame
-from pydantic import Field
-from phc.easy.auth import Auth
-from phc.easy.paging_api_item import PagingApiItem, PagingApiOptions
-
 from enum import Enum
+from typing import List, Optional
 
+from phc.easy.paging_api_item import PagingApiOptions
+from pydantic import Field
 
 MAPPINGS = {
     "variant_set_ids": "variantSetIds",
@@ -115,105 +110,3 @@ class GenomicShortVariantOptions(PagingApiOptions):
             value = ",".join(value)
 
         return (MAPPINGS.get(key, key), value)
-
-
-class GenomicShortVariant(PagingApiItem):
-    @staticmethod
-    def resource_path():
-        return "genomics/variants"
-
-    @staticmethod
-    def params_class():
-        return GenomicShortVariantOptions
-
-    @staticmethod
-    def transform_results(data_frame: pd.DataFrame, **expand_args):
-        args = {
-            **expand_args,
-            "custom_columns": [
-                *expand_args.get("custom_columns", []),
-                *[
-                    Frame.codeable_like_column_expander(k)
-                    for k in ["clinvar", "cosmic", "vcf"]
-                ],
-            ],
-        }
-
-        return Frame.expand(data_frame, **args)
-
-    @classmethod
-    def get_data_frame(
-        cls,
-        # Query parameters
-        variant_set_ids: List[str],
-        include: List[GenomicShortVariantInclude] = ["vcf"],
-        gene: List[str] = [],
-        rsid: List[str] = [],
-        chromosome: List[str] = [],
-        clinvar_allele_id: List[str] = [],
-        clinvar_disease: List[str] = [],
-        clinvar_review: List[str] = [],
-        clinvar_significance: List[str] = [],
-        cosmic_id: List[str] = [],
-        cosmic_status: List[str] = [],
-        cosmic_histology: List[str] = [],
-        cosmic_tumor_site: List[str] = [],
-        variant_class: List[str] = [],
-        group: List[str] = [],
-        impact: List[str] = [],
-        transcript_id: List[str] = [],
-        biotype: List[str] = [],
-        amino_acid_change: List[str] = [],
-        sequence_type: List[str] = [],
-        position: List[str] = [],
-        cosmic_sample_count: List[str] = [],
-        min_allele_frequency: List[str] = [],
-        max_allele_frequency: List[str] = [],
-        pop_allele_frequency: List[str] = [],
-        exac_allele_frequency: List[str] = [],
-        exac_homozygous: List[str] = [],
-        dbnsfp_damaging_count: List[str] = [],
-        dbnsfp_damaging_predictor: List[str] = [],
-        dbnsfp_damaging_vote: List[str] = [],
-        dbnsfp_fathmm_rankscore: List[str] = [],
-        dbnsfp_fathmm_pred: List[str] = [],
-        dbnsfp_mean_rankscore: List[str] = [],
-        dbnsfp_mean_rankscore_predictor: List[str] = [],
-        dbnsfp_mutationtaster_rankscore: List[str] = [],
-        dbnsfp_mutationtaster_pred: List[str] = [],
-        dbnsfp_sift_rankscore: List[str] = [],
-        dbnsfp_sift_pred: List[str] = [],
-        zygosity: List[str] = [],
-        genotype: List[str] = [],
-        variant_allele_frequency: List[str] = [],
-        quality: List[str] = [],
-        read_depth: List[str] = [],
-        alt_read_depth: List[str] = [],
-        ref_read_depth: List[str] = [],
-        variant_filter: List[str] = [],
-        drug_associations: Optional[bool] = None,
-        # Execution parameters,
-        all_results: bool = False,
-        auth_args: Auth = Auth.shared(),
-        max_pages: Optional[int] = None,
-        page_size: Optional[int] = None,
-        log: bool = False,
-        **kw_args,
-    ):
-        """Execute a request for genomic short variants
-
-        ## Parameters
-
-        Query: `GenomicShortVariantOptions`
-
-        Execution: `phc.easy.query.Query.execute_paging_api`
-
-        Expansion: `phc.easy.frame.Frame.expand`
-
-        NOTE:
-         - `variant_class` is translated to `class` as a parameter
-         - `variant_filter` is translated to `filter` as a parameter
-        """
-        return super().get_data_frame(
-            **kw_args, **cls._get_current_args(inspect.currentframe(), locals())
-        )


Test patch:
diff --git a/tests/test_genomic_short_variant.py b/tests/test_genomic_short_variant.py
new file mode 100644
index 0000000..4e1c289
--- /dev/null
+++ b/tests/test_genomic_short_variant.py
@@ -0,0 +1,28 @@
+import pandas as pd
+from phc.easy.omics.genomic_short_variant import GenomicShortVariant
+
+
+def test_parse_id():
+    raw_df = pd.DataFrame(
+        # NOTE: Sample is taken and adapted from BRCA data set
+        [
+            {"id": "f0e381b6-a9b3-4411-af56-7f7f5ce3ce6b:XjQLzpOuLm=:GOLGA3"},
+            {"id": "f0e381b6-a9b3-4411-af56-7f7f5ce3ce6b:naTuKl96CL=:ESCO1"},
+            {"id": "6b0591ce-7b3b-4b04-85bc-d17e463ca869:A235y+Jw+v=:MAP3K13"},
+            {"id": "f0e381b6-a9b3-4411-af56-7f7f5ce3ce6b:dOML6l4/uk=:MAP3K7"},
+            {"id": "f0e381b6-a9b3-4411-af56-7f7f5ce3ce6b:tCkWMHDLL7=:CACNA1B"},
+            {"id": "6b0591ce-7b3b-4b04-85bc-d17e463ca869:3szKb4RVAR=:PCDHB7"},
+            {"id": "6b0591ce-7b3b-4b04-85bc-d17e463ca869:BsZ3G0NtUz=:FASN"},
+        ]
+    )
+
+    frame = GenomicShortVariant.transform_results(raw_df)
+
+    assert frame.columns.values.tolist() == ["id", "variant_set_id", "gene"]
+
+    assert frame.variant_set_id.unique().tolist() == [
+        "f0e381b6-a9b3-4411-af56-7f7f5ce3ce6b",
+        "6b0591ce-7b3b-4b04-85bc-d17e463ca869",
+    ]
+
+    assert "FASN" in frame.gene.values.tolist()