Skip to content

Commit 7eec70e

Browse files
committed
Rework methods
1 parent 469bc42 commit 7eec70e

File tree

3 files changed

+86
-88
lines changed

3 files changed

+86
-88
lines changed

cg/meta/upload/scout/uploadscoutapi.py

Lines changed: 19 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
from pathlib import Path
55

66
from housekeeper.store.models import File, Version
7-
from pydantic.dataclasses import dataclass
87

98
from cg.apps.housekeeper.hk import HousekeeperAPI
109
from cg.apps.lims import LimsAPI
@@ -26,22 +25,13 @@
2625
from cg.meta.workflow.analysis import AnalysisAPI
2726
from cg.meta.workflow.utils.genome_build_helpers import genome_to_scout_format, get_genome_build
2827
from cg.models.scout.scout_load_config import ScoutLoadConfig
28+
from cg.store.api.data_classes import RNADNACollection
2929
from cg.store.models import Analysis, Case, Customer, Sample
3030
from cg.store.store import Store
3131

3232
LOG = logging.getLogger(__name__)
3333

3434

35-
@dataclass
36-
class RNADNACollection:
37-
"""Contains the id for an RNA sample, the name of its connected DNA sample,
38-
and a list of connected, uploaded DNA cases."""
39-
40-
rna_sample_internal_id: str
41-
dna_sample_name: str
42-
dna_case_ids: list[str]
43-
44-
4535
class UploadScoutAPI:
4636
"""Class that handles everything that has to do with uploading to Scout."""
4737

@@ -197,9 +187,11 @@ def get_rna_alignment_cram(self, case_id: str, sample_id: str) -> File | None:
197187
def upload_rna_alignment_file(self, case_id: str, dry_run: bool) -> None:
198188
"""Upload RNA alignment file to Scout."""
199189
rna_case: Case = self.status_db.get_case_by_internal_id(case_id)
200-
rna_dna_collections: list[RNADNACollection] = self.create_rna_dna_collections(rna_case)
190+
rna_dna_collections: list[RNADNACollection] = (
191+
self.status_db.get_related_dna_cases_with_samples(rna_case)
192+
)
201193
for rna_dna_collection in rna_dna_collections:
202-
rna_sample_internal_id: str = rna_dna_collection.rna_sample_internal_id
194+
rna_sample_internal_id: str = rna_dna_collection.rna_sample_id
203195
dna_sample_name: str = rna_dna_collection.dna_sample_name
204196
rna_alignment_cram: File | None = self.get_rna_alignment_cram(
205197
case_id=case_id, sample_id=rna_sample_internal_id
@@ -337,9 +329,11 @@ def upload_rna_coverage_bigwig_to_scout(self, case_id: str, dry_run: bool) -> No
337329

338330
status_db: Store = self.status_db
339331
rna_case = status_db.get_case_by_internal_id(case_id)
340-
rna_dna_collections: list[RNADNACollection] = self.create_rna_dna_collections(rna_case)
332+
rna_dna_collections: list[RNADNACollection] = (
333+
self.status_db.get_related_dna_cases_with_samples(rna_case)
334+
)
341335
for rna_dna_collection in rna_dna_collections:
342-
rna_sample_internal_id: str = rna_dna_collection.rna_sample_internal_id
336+
rna_sample_internal_id: str = rna_dna_collection.rna_sample_id
343337
dna_sample_name: str = rna_dna_collection.dna_sample_name
344338
rna_coverage_bigwig: File | None = self.get_rna_coverage_bigwig(
345339
case_id=case_id, sample_id=rna_sample_internal_id
@@ -373,7 +367,7 @@ def upload_omics_sample_id_to_scout(
373367
self, dry_run: bool, rna_dna_collections: list[RNADNACollection]
374368
) -> None:
375369
for rna_dna_collection in rna_dna_collections:
376-
rna_sample_internal_id: str = rna_dna_collection.rna_sample_internal_id
370+
rna_sample_internal_id: str = rna_dna_collection.rna_sample_id
377371
dna_sample_name: str = rna_dna_collection.dna_sample_name
378372
for dna_case_id in rna_dna_collection.dna_case_ids:
379373
LOG.info(
@@ -397,7 +391,7 @@ def upload_rna_fraser_outrider_to_scout(
397391
"""Upload omics fraser and outrider file for a case to Scout."""
398392
status_db: Store = self.status_db
399393
for rna_dna_collection in rna_dna_collections:
400-
rna_sample_internal_id: str = rna_dna_collection.rna_sample_internal_id
394+
rna_sample_internal_id: str = rna_dna_collection.rna_sample_id
401395
dna_sample_name: str = rna_dna_collection.dna_sample_name
402396
rna_fraser: File | None = self.get_rna_omics_fraser(case_id=case_id)
403397
rna_outrider: File | None = self.get_rna_omics_outrider(case_id=case_id)
@@ -433,7 +427,7 @@ def upload_rna_fraser_outrider_to_scout(
433427
def upload_rna_genome_build_to_scout(
434428
self,
435429
dry_run: bool,
436-
rna_case: str,
430+
rna_case: Case,
437431
rna_dna_collections: list[RNADNACollection],
438432
) -> None:
439433
"""Upload RNA genome built for a RNA/DNA case to Scout."""
@@ -493,9 +487,11 @@ def upload_splice_junctions_bed_to_scout(self, dry_run: bool, case_id: str) -> N
493487
status_db: Store = self.status_db
494488
rna_case: Case = status_db.get_case_by_internal_id(case_id)
495489

496-
rna_dna_collections: list[RNADNACollection] = self.create_rna_dna_collections(rna_case)
490+
rna_dna_collections: list[RNADNACollection] = (
491+
self.status_db.get_related_dna_cases_with_samples(rna_case)
492+
)
497493
for rna_dna_collection in rna_dna_collections:
498-
rna_sample_internal_id: str = rna_dna_collection.rna_sample_internal_id
494+
rna_sample_internal_id: str = rna_dna_collection.rna_sample_id
499495
dna_sample_name: str = rna_dna_collection.dna_sample_name
500496
splice_junctions_bed: File | None = self.get_splice_junctions_bed(
501497
case_id=case_id, sample_id=rna_sample_internal_id
@@ -606,7 +602,9 @@ def upload_rna_omics_to_scout(self, dry_run: bool, case_id: str) -> None:
606602
"""Upload RNA omics files to Scout."""
607603
status_db: Store = self.status_db
608604
rna_case = status_db.get_case_by_internal_id(case_id)
609-
rna_dna_collections: list[RNADNACollection] = self.create_rna_dna_collections(rna_case)
605+
rna_dna_collections: list[RNADNACollection] = (
606+
self.status_db.get_related_dna_cases_with_samples(rna_case)
607+
)
610608
self.upload_omics_sample_id_to_scout(
611609
dry_run=dry_run, rna_dna_collections=rna_dna_collections
612610
)
@@ -666,48 +664,6 @@ def get_config_builder(self, analysis, hk_version) -> ScoutConfigBuilder:
666664

667665
return config_builders[analysis.workflow]
668666

669-
def create_rna_dna_collections(self, rna_case: Case) -> list[RNADNACollection]:
670-
return [
671-
self.create_rna_dna_collection(rna_sample=link.sample, customer=rna_case.customer)
672-
for link in rna_case.links
673-
]
674-
675-
def create_rna_dna_collection(self, rna_sample: Sample, customer: Customer) -> RNADNACollection:
676-
"""Creates a collection containing the given RNA sample id, its related DNA sample name, and
677-
a list of ids for the DNA cases connected to the DNA sample."""
678-
if not rna_sample.subject_id:
679-
raise CgDataError(
680-
f"Failed to link RNA sample {rna_sample.internal_id} to DNA samples - subject_id field is empty."
681-
)
682-
683-
collaborators: set[Customer] = customer.collaborators
684-
subject_id_samples: list[Sample] = (
685-
self.status_db.get_samples_by_customer_ids_and_subject_id_and_is_tumour(
686-
customer_ids=[customer.id for customer in collaborators],
687-
subject_id=rna_sample.subject_id,
688-
is_tumour=rna_sample.is_tumour,
689-
)
690-
)
691-
692-
subject_id_dna_samples: list[Sample] = self._get_application_prep_category(
693-
subject_id_samples
694-
)
695-
696-
if len(subject_id_dna_samples) != 1:
697-
raise CgDataError(
698-
f"Failed to upload files for RNA case: unexpected number of DNA sample matches for subject_id: "
699-
f"{rna_sample.subject_id}. Number of matches: {len(subject_id_dna_samples)} "
700-
)
701-
dna_sample: Sample = subject_id_dna_samples[0]
702-
dna_cases: list[str] = self._dna_cases_related_to_dna_sample(
703-
dna_sample=dna_sample, collaborators=collaborators
704-
)
705-
return RNADNACollection(
706-
rna_sample_internal_id=rna_sample.internal_id,
707-
dna_sample_name=dna_sample.name,
708-
dna_case_ids=dna_cases,
709-
)
710-
711667
def _dna_cases_related_to_dna_sample(
712668
self, dna_sample: Sample, collaborators: set[Customer]
713669
) -> list[str]:

cg/store/api/data_classes.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from pydantic.dataclasses import dataclass
2+
3+
4+
@dataclass
5+
class RNADNACollection:
6+
"""Contains the id for an RNA sample, the name of its connected DNA sample,
7+
and a list of connected, uploaded DNA cases."""
8+
9+
rna_sample_id: str
10+
dna_sample_name: str
11+
dna_case_ids: list[str]

cg/store/crud/read.py

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
SampleType,
1616
)
1717
from cg.constants.sequencing import DNA_PREP_CATEGORIES, SeqLibraryPrepCategory
18-
from cg.exc import CaseNotFoundError, CgError, OrderNotFoundError, SampleNotFoundError
18+
from cg.exc import CaseNotFoundError, CgDataError, CgError, OrderNotFoundError, SampleNotFoundError
1919
from cg.models.orders.constants import OrderType
2020
from cg.models.orders.sample_base import SexEnum
2121
from cg.server.dto.samples.collaborator_samples_request import CollaboratorSamplesRequest
2222
from cg.services.orders.order_service.models import OrderQueryParams
23+
from cg.store.api.data_classes import RNADNACollection
2324
from cg.store.base import BaseHandler
2425
from cg.store.exc import EntryNotFoundError
2526
from cg.store.filters.status_analysis_filters import AnalysisFilter, apply_analysis_filter
@@ -1671,33 +1672,63 @@ def get_uploaded_related_dna_cases(self, rna_case: Case) -> list[Case]:
16711672
prep_categories=DNA_PREP_CATEGORIES,
16721673
collaborators=collaborators,
16731674
)
1674-
1675-
dna_samples_cases_analysis_query: Query = (
1676-
related_dna_samples_query.join(Sample.links).join(CaseSample.case).join(Analysis)
1677-
)
1678-
1679-
dna_samples_cases_analysis_query: Query = apply_case_filter(
1680-
cases=dna_samples_cases_analysis_query,
1681-
workflows=DNA_WORKFLOWS_WITH_SCOUT_UPLOAD,
1682-
customer_entry_ids=[customer.id for customer in collaborators],
1683-
filter_functions=[
1684-
CaseFilter.BY_WORKFLOWS,
1685-
CaseFilter.BY_CUSTOMER_ENTRY_IDS,
1686-
],
1687-
)
1688-
1689-
uploaded_dna_cases: list[Case] = (
1690-
apply_analysis_filter(
1691-
analyses=dna_samples_cases_analysis_query,
1692-
filter_functions=[AnalysisFilter.IS_UPLOADED],
1693-
)
1694-
.with_entities(Case)
1695-
.all()
1675+
customer_ids: list[int] = [customer.id for customer in collaborators]
1676+
uploaded_dna_cases: list[Case] = self._get_uploaded_dna_cases(
1677+
sample_query=related_dna_samples_query, customer_ids=customer_ids
16961678
)
1697-
1698-
related_dna_cases.extend([case for case in uploaded_dna_cases])
1679+
related_dna_cases.extend(uploaded_dna_cases)
16991680
if not related_dna_cases:
17001681
raise CaseNotFoundError(
17011682
f"No matching uploaded DNA cases for case {rna_case.internal_id} ({rna_case.name})."
17021683
)
17031684
return related_dna_cases
1685+
1686+
def _get_uploaded_dna_cases(self, sample_query: Query, customer_ids: list[int]) -> list[Case]:
1687+
dna_samples_cases_analysis_query: Query = (
1688+
sample_query.join(Sample.links).join(CaseSample.case).join(Analysis)
1689+
)
1690+
dna_samples_cases_analysis_query: Query = apply_case_filter(
1691+
cases=dna_samples_cases_analysis_query,
1692+
workflows=DNA_WORKFLOWS_WITH_SCOUT_UPLOAD,
1693+
customer_entry_ids=customer_ids,
1694+
filter_functions=[
1695+
CaseFilter.BY_WORKFLOWS,
1696+
CaseFilter.BY_CUSTOMER_ENTRY_IDS,
1697+
],
1698+
)
1699+
uploaded_dna_cases: list[Case] = (
1700+
apply_analysis_filter(
1701+
analyses=dna_samples_cases_analysis_query,
1702+
filter_functions=[AnalysisFilter.IS_UPLOADED],
1703+
)
1704+
.with_entities(Case)
1705+
.all()
1706+
)
1707+
return uploaded_dna_cases
1708+
1709+
def get_related_dna_cases_with_samples(self, rna_case: Case) -> list[RNADNACollection]:
1710+
collaborators = rna_case.customer.collaborators
1711+
collaborator_ids: list[int] = [collaborator.id for collaborator in collaborators]
1712+
rna_dna_collections: list[RNADNACollection] = []
1713+
for sample in rna_case.samples:
1714+
related_dna_samples: Query = self._get_related_samples_query(
1715+
sample=sample, prep_categories=DNA_PREP_CATEGORIES, collaborators=collaborators
1716+
)
1717+
nr_of_related_samples: int = related_dna_samples.count()
1718+
if nr_of_related_samples != 1:
1719+
raise CgDataError(
1720+
f"Failed to upload files for RNA case: unexpected number of DNA sample matches for subject_id: "
1721+
f"{sample.subject_id}. Number of matches: {nr_of_related_samples} "
1722+
)
1723+
dna_sample_name: str = related_dna_samples.first().name
1724+
dna_cases: list[Case] = self._get_uploaded_dna_cases(
1725+
sample_query=related_dna_samples, customer_ids=collaborator_ids
1726+
)
1727+
dna_case_ids: list[str] = [case.internal_id for case in dna_cases]
1728+
collection = RNADNACollection(
1729+
rna_sample_id=sample.internal_id,
1730+
dna_sample_name=dna_sample_name,
1731+
dna_case_ids=dna_case_ids,
1732+
)
1733+
rna_dna_collections.append(collection)
1734+
return rna_dna_collections

0 commit comments

Comments
 (0)