Skip to content

Commit

Permalink
Add variants related models
Browse files Browse the repository at this point in the history
  • Loading branch information
gregorjerse committed Sep 12, 2024
1 parent 74ba4ec commit 08d00ca
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Changed
Added
-----
- Add ``restart`` method to the ``Data`` resource
- Add variants related models

Fixed
-----
Expand Down
4 changes: 3 additions & 1 deletion src/resdk/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,9 @@ def _add_filter(self, filter_):
"""Add filtering parameters."""
for key, value in filter_.items():
# 'sample' is called 'entity' in the backend.
key = key.replace("sample", "entity")
if not key.startswith("variant_calls__"):
key = key.replace("sample", "entity")
print("Adding filter", key, value)
value = self._dehydrate_resources(value)
if self._non_string_iterable(value):
value = ",".join(map(str, value))
Expand Down
9 changes: 9 additions & 0 deletions src/resdk/resolwe.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
Relation,
Sample,
User,
Variant,
VariantAnnotation,
VariantCall,
VariantExperiment,
)
from .resources.base import BaseResource
from .resources.kb import Feature, Mapping
Expand Down Expand Up @@ -114,6 +118,10 @@ class Resolwe:
resource_query_mapping = {
AnnotationField: "annotation_field",
AnnotationValue: "annotation_value",
Variant: "variant",
VariantAnnotation: "variant_annotation",
VariantExperiment: "variant_experiment",
VariantCall: "variant_calls",
Data: "data",
Collection: "collection",
Sample: "sample",
Expand All @@ -126,6 +134,7 @@ class Resolwe:
Mapping: "mapping",
Geneset: "geneset",
Metadata: "metadata",
Variant: "variant",
}
# Map ResolweQuery name to it's slug_field
slug_field_mapping = {
Expand Down
9 changes: 9 additions & 0 deletions src/resdk/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@
:members:
:inherited-members:
.. autoclass:: resdk.resources.Variants
:members:
:inherited-members:
.. autoclass:: resdk.resources.User
:members:
:inherited-members:
Expand Down Expand Up @@ -102,6 +106,7 @@
from .relation import Relation
from .sample import Sample
from .user import Group, User
from .variants import Variant, VariantAnnotation, VariantCall, VariantExperiment

__all__ = (
"AnnotationField",
Expand All @@ -117,4 +122,8 @@
"Process",
"Relation",
"User",
"Variant",
"VariantAnnotation",
"VariantCall",
"VariantExperiment",
)
12 changes: 11 additions & 1 deletion src/resdk/resources/sample.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
"""Sample resource."""

import logging
from typing import TYPE_CHECKING, Any, Dict, Optional
from typing import TYPE_CHECKING, Any, Dict, List, Optional

from resdk.exceptions import ResolweServerError
from resdk.shortcuts.sample import SampleUtilsMixin

from ..utils.decorators import assert_object_exists
from .background_task import BackgroundTask
from .collection import BaseCollection, Collection
from .variants import Variant

if TYPE_CHECKING:
from .annotations import AnnotationValue
Expand Down Expand Up @@ -39,6 +40,8 @@ def __init__(self, resolwe, **model_data):
self._background = None
#: is this sample background to any other sample?
self._is_background = None
#: list of ``Variant`` objects attached to the sample
self._variants = None

super().__init__(resolwe, **model_data)

Expand All @@ -60,6 +63,13 @@ def data(self):

return self._data

@property
def variants(self):
"""Get variants."""
if self._variants is None:
self._variants = self.resolwe.variant.filter(variant_calls__sample=self.id)
return self._variants

@property
def collection(self):
"""Get collection."""
Expand Down
94 changes: 94 additions & 0 deletions src/resdk/resources/variants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
"""Variant resources."""

from .base import BaseResource


class Variant(BaseResource):
"""ResolweBio Variant resource."""

endpoint = "variant"

READ_ONLY_FIELDS = BaseResource.READ_ONLY_FIELDS + (
"species",
"genome_assembly",
"chromosome",
"position",
"reference",
"alternative",
)

def __init__(self, resolwe, **model_data):
"""Initialize object."""
super().__init__(resolwe, **model_data)
self._annotations = None

@property
def annotations(self):
"""Get the annotations for this variant."""
if self._annotations is None:
self._annotations = self.resolwe.variant_annotation.filter(id=self.id)
return self._annotations

def __repr__(self) -> str:
"""Return string representation."""
return (
f"Variant <chr: {self.chromosome}, pos: {self.position}, "
f"ref: {self.reference}, alt: {self.alternative}>"
)


class VariantAnnotation(BaseResource):
"""VariantAnnotation resource."""

endpoint = "variant_annotations"

READ_ONLY_FIELDS = BaseResource.READ_ONLY_FIELDS + (
"variant_id",
"type",
"clinical_diagnosis",
"clinical_significance",
"dbsnp_id",
"clinvar_id",
"data",
"transcripts",
)

def __repr__(self) -> str:
"""Return string representation."""
return f"VariantAnnotation <variant: {self.variant_id}>"


class VariantExperiment(BaseResource):
"""Variant experiment resource."""

endpoint = "variant_experiment"

READ_ONLY_FIELDS = BaseResource.READ_ONLY_FIELDS + (
"variant_data_source",
"timestamp",
"contributor",
)


class VariantCall(BaseResource):
"""VariantCall resource."""

endpoint = "variant_calls"

READ_ONLY_FIELDS = BaseResource.READ_ONLY_FIELDS + (
"sample",
"variant",
"experiment",
"quality",
"depth_norm_quality",
"alternative_allele_depth",
"depth",
"genotype",
"genotype_quality",
"filter",
"data",
)

def __repr__(self) -> str:
"""Return string representation."""
return f"VariantCall <pk: {self.id}>"

0 comments on commit 08d00ca

Please sign in to comment.