cg 83.15.0__py3-none-any.whl → 83.15.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
cg/__init__.py CHANGED
@@ -1,2 +1,2 @@
1
1
  __title__ = "cg"
2
- __version__ = "83.15.0"
2
+ __version__ = "83.15.2"
@@ -1,4 +1,5 @@
1
1
  import logging
2
+
2
3
  import rich_click as click
3
4
 
4
5
  from cg.models.cg_config import CGConfig
@@ -11,4 +12,6 @@ LOG = logging.getLogger(__name__)
11
12
  @click.pass_obj
12
13
  def sequencing_qc(context: CGConfig):
13
14
  service: SequencingQCService = context.sequencing_qc_service
14
- service.run_sequencing_qc()
15
+ succeeded: bool = service.run_sequencing_qc()
16
+ if not succeeded:
17
+ raise click.Abort
cg/exc.py CHANGED
@@ -356,5 +356,9 @@ class SeqeraError(CgError):
356
356
  """Exception raised when receiving an unexpected response from Seqera platform"""
357
357
 
358
358
 
359
+ class MultipleCaptureKitsError(CgError):
360
+ """Exception raised when multiple capture kits are found where only one is expected."""
361
+
362
+
359
363
  class ApplicationDoesNotHaveHiFiYieldError(CgError):
360
364
  """Exception raised when application does not have HiFi yield set."""
@@ -2,8 +2,9 @@ import logging
2
2
  from pathlib import Path
3
3
  from typing import cast
4
4
 
5
+ from cg.apps.lims.api import LimsAPI
5
6
  from cg.constants.priority import SlurmQos
6
- from cg.exc import CaseNotConfiguredError
7
+ from cg.exc import CaseNotConfiguredError, MultipleCaptureKitsError
7
8
  from cg.meta.workflow.fastq import BalsamicFastqHandler
8
9
  from cg.models.cg_config import BalsamicConfig
9
10
  from cg.services.analysis_starter.configurator.configurator import Configurator
@@ -11,6 +12,7 @@ from cg.services.analysis_starter.configurator.file_creators.balsamic_config imp
11
12
  BalsamicConfigFileCreator,
12
13
  )
13
14
  from cg.services.analysis_starter.configurator.models.balsamic import BalsamicCaseConfig
15
+ from cg.store.models import Case
14
16
  from cg.store.store import Store
15
17
 
16
18
  LOG = logging.getLogger(__name__)
@@ -22,6 +24,7 @@ class BalsamicConfigurator(Configurator):
22
24
  config: BalsamicConfig,
23
25
  config_file_creator: BalsamicConfigFileCreator,
24
26
  fastq_handler: BalsamicFastqHandler,
27
+ lims_api: LimsAPI,
25
28
  store: Store,
26
29
  ):
27
30
  self.store: Store = store
@@ -35,9 +38,11 @@ class BalsamicConfigurator(Configurator):
35
38
 
36
39
  self.fastq_handler: BalsamicFastqHandler = fastq_handler
37
40
  self.config_file_creator: BalsamicConfigFileCreator = config_file_creator
41
+ self.lims_api = lims_api
38
42
 
39
43
  def configure(self, case_id: str, **flags) -> BalsamicCaseConfig:
40
44
  LOG.info(f"Configuring case {case_id}")
45
+ self._ensure_consistent_capture_kits(case_id)
41
46
  self.fastq_handler.link_fastq_files(case_id)
42
47
  fastq_path: Path = self.fastq_handler.get_fastq_dir(case_id)
43
48
  self.config_file_creator.create(case_id=case_id, fastq_path=fastq_path, **flags)
@@ -61,6 +66,16 @@ class BalsamicConfigurator(Configurator):
61
66
  def _get_sample_config_path(self, case_id: str) -> Path:
62
67
  return Path(self.root_dir, case_id, f"{case_id}.json")
63
68
 
69
+ def _ensure_consistent_capture_kits(self, case_id):
70
+ case: Case = self.store.get_case_by_internal_id_strict(case_id)
71
+ capture_kits: set[str | None] = {
72
+ self.lims_api.capture_kit(sample.internal_id) for sample in case.samples
73
+ }
74
+ if len(capture_kits) > 1:
75
+ raise MultipleCaptureKitsError(
76
+ f"Multiple capture kits found for {case_id}: {capture_kits}"
77
+ )
78
+
64
79
  def _ensure_required_config_files_exist(self, config: BalsamicCaseConfig) -> None:
65
80
  if not config.sample_config.exists():
66
81
  raise CaseNotConfiguredError(
@@ -228,6 +228,7 @@ class ConfiguratorFactory:
228
228
  status_db=self.store,
229
229
  ),
230
230
  config=self.cg_config.balsamic,
231
+ lims_api=self.lims_api,
231
232
  store=self.store,
232
233
  )
233
234
 
@@ -18,9 +18,15 @@ class SequencingQCService:
18
18
  def __init__(self, store: Store):
19
19
  self.store = store
20
20
 
21
- def run_sequencing_qc(self) -> None:
22
- """Run QC for samples in pending or failed cases and store the aggregated score on each case."""
21
+ def run_sequencing_qc(self) -> bool:
22
+ """
23
+ Run QC for samples in pending or failed cases and store the aggregated score on each case.
24
+ Return True if all checks could run succesfully
25
+ Return False if at least one of the checks raised an exception
26
+ """
23
27
  cases: list[Case] = self.store.get_cases_for_sequencing_qc()
28
+ all_checks_ran_succesfully: bool = True
29
+
24
30
  for case in cases:
25
31
  LOG.debug(f"Performing sequencing QC for case: {case.internal_id}")
26
32
  try:
@@ -30,6 +36,9 @@ class SequencingQCService:
30
36
  LOG.info(f"Sequencing QC status for case {case.internal_id}: {qc_status}")
31
37
  except Exception as e:
32
38
  LOG.error(f"Error found during sequencing QC of case: {case.internal_id}: {e}")
39
+ all_checks_ran_succesfully = False
40
+
41
+ return all_checks_ran_succesfully
33
42
 
34
43
  @staticmethod
35
44
  def case_pass_sequencing_qc(case: Case) -> bool:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cg
3
- Version: 83.15.0
3
+ Version: 83.15.2
4
4
  Summary: Clinical Genomics command center
5
5
  Requires-Python: >=3.11,<3.13
6
6
  Classifier: Programming Language :: Python
@@ -1,4 +1,4 @@
1
- cg/__init__.py,sha256=LzHKmL8dVmAmq-6AHs2IvH5WkbB5nsiiArjFCiCZoEA,41
1
+ cg/__init__.py,sha256=h1_DpaXm14buebvsKjVmxOLYjMT2n5LWfEifGHaVN3I,41
2
2
  cg/apps/__init__.py,sha256=pYf0vxo4iYQqURzFRYzqpOCdV8Cm9MWx0GHvJOz0EMg,315
3
3
  cg/apps/coverage/__init__.py,sha256=dJtsmNf8tODE2-VEomMIoYA7ugLYZAk_upsfOQCZeF8,27
4
4
  cg/apps/coverage/api.py,sha256=e_ozC3QeNKoEfpjjMaL-XjeBLtz-JySWccrtw0E9mLM,2940
@@ -104,7 +104,7 @@ cg/cli/get.py,sha256=sqKX2tDWnCE6zTwcMBCOb796Bc9rvu1AYLkONQ3Sq0w,8852
104
104
  cg/cli/post_process/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
105
105
  cg/cli/post_process/post_process.py,sha256=f6bCOsNLIHYHJdbKBVcjRO684MS258CptsmAVknoYI0,2367
106
106
  cg/cli/post_process/utils.py,sha256=XrzBhVDybFa4sBGDz5Dbwah0YrYD1IS_j3WzPjWjUfs,3193
107
- cg/cli/sequencing_qc/sequencing_qc.py,sha256=UxdfUBryKq5Pj82-8Ihjmqb9EClNzcuJtZKrB7YAB_A,427
107
+ cg/cli/sequencing_qc/sequencing_qc.py,sha256=anMscRw9Ulp3t2tQuLNuPE1HDtWTISgh_4yJourvAyA,494
108
108
  cg/cli/set/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
109
109
  cg/cli/set/base.py,sha256=gqdDpKS32rM29sQxPyK6fLf0Of6G1Un7htkAxZHkvKo,10453
110
110
  cg/cli/set/case.py,sha256=5QFZdnp7XdyaPFl6KDtM31TkX5XFjgOtRjQM2umb3Qk,4613
@@ -225,7 +225,7 @@ cg/constants/slurm.py,sha256=_Y_InISKpGKT-oVMnES7k7Csz2G1l52MNtJwBZm0prI,313
225
225
  cg/constants/subject.py,sha256=EE26Emu6T3_HWvsWeuI5GRGGIvB0BwCjN53KHrsr18U,577
226
226
  cg/constants/symbols.py,sha256=c06D1mYFWstZbVEgiby2lUNriswUPVRU5TnSSy889tY,71
227
227
  cg/constants/tb.py,sha256=UJHdsu109oR_zxvQrko9SqFANiSUn_UJTw5BFebWcds,621
228
- cg/exc.py,sha256=IYYRa6saq17OT8pA_PBdiorf2XyXTaxNV20JBkdx8QE,8418
228
+ cg/exc.py,sha256=lGr9DFUkOyXzK9y1bF2qxRZT_Tp2Falb5fmAa8fdM94,8553
229
229
  cg/io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
230
230
  cg/io/api.py,sha256=WaiompYmK4bkl94fZkGzP2CTsQPmHaTSvy0oD0SKw4s,1037
231
231
  cg/io/controller.py,sha256=4TTHm9fNY7Ti3S0r-uhxB3oycJ-Ni5Y44lFj5Yvl3_I,2978
@@ -544,7 +544,7 @@ cg/services/analysis_starter/configurator/file_creators/nextflow/sample_sheet/rn
544
544
  cg/services/analysis_starter/configurator/file_creators/nextflow/sample_sheet/taxprofiler_sample_sheet_creator.py,sha256=dBbgE0TtZG3xNRrOkLbiGQdY2ZVfCKUsSL4jUOotNuo,1757
545
545
  cg/services/analysis_starter/configurator/file_creators/nextflow/sample_sheet/tomte_sample_sheet_creator.py,sha256=8OsMI7ZbcEHsPZAwbG1YRklINBISxsiyli5iaRspKYY,1488
546
546
  cg/services/analysis_starter/configurator/file_creators/nextflow/utils.py,sha256=Fr7s-_lo6UHwmmWt4peeW0eZBxB7KZcE_S2CykdIr1M,559
547
- cg/services/analysis_starter/configurator/implementations/balsamic.py,sha256=-5Omv61f20lQsVf5G_5NCwNPXn-BrRBdgu6XjfrrNUo,2894
547
+ cg/services/analysis_starter/configurator/implementations/balsamic.py,sha256=YUvWwLZlNonqzFUxDKnMwIbtHcGMX1bekiVBR0manCk,3539
548
548
  cg/services/analysis_starter/configurator/implementations/microsalt.py,sha256=4bqeDS2LjV5Dl2cQkAb3FOTQ3uEoOXkSMyHP1lhkUKQ,3350
549
549
  cg/services/analysis_starter/configurator/implementations/mip_dna.py,sha256=dhzXUGNvFDpgHL-o2Fh24WlDHpJpVrk0bKRrIbm4Ik8,5073
550
550
  cg/services/analysis_starter/configurator/implementations/nextflow.py,sha256=hNbFybR1PdpZyasNMMWmVfSRQuLR1NT26dEo8lYldD4,6947
@@ -553,7 +553,7 @@ cg/services/analysis_starter/configurator/models/microsalt.py,sha256=PvwYS9sL1hh
553
553
  cg/services/analysis_starter/configurator/models/mip_dna.py,sha256=-9wiSIPeqp7McCnS_MWYS7DqkAoB0BEXVVYGnov1QUg,1156
554
554
  cg/services/analysis_starter/configurator/models/nextflow.py,sha256=Ug-Kj179TW5hnaCBPJFu9rigbBnmFYSfv02kkItmn2o,610
555
555
  cg/services/analysis_starter/constants.py,sha256=69R7TyZWXQlDMowpV87faHcY7zpH5KTTjHLViYadeo8,268
556
- cg/services/analysis_starter/factories/configurator_factory.py,sha256=2K3vTqNd-6eZCeajTZ3PsOuik9CUSfrksKulQ7es_jE,12259
556
+ cg/services/analysis_starter/factories/configurator_factory.py,sha256=CB9iyjaH43cEMQb9_Q9JdHGbLvodEwhhXKZatZhkcEI,12295
557
557
  cg/services/analysis_starter/factories/starter_factory.py,sha256=hhM-5pRgklJiQ-vZYEyD0bwZ_v1IcybMfVCeKC_ySR8,6138
558
558
  cg/services/analysis_starter/input_fetcher/implementations/bam_fetcher.py,sha256=ttpexbRji6VjlxYi_ayevfjNAtgkV25OQbAV7fagKYA,2530
559
559
  cg/services/analysis_starter/input_fetcher/implementations/fastq_fetcher.py,sha256=P2NVYgjLNwnmRsebuVVMUA4_ks-1wx2ALfHBxoucmUg,9676
@@ -855,7 +855,7 @@ cg/services/sample_run_metrics_service/utils.py,sha256=BwICxptnhGg8oBghCLhzHaMNu
855
855
  cg/services/sequencing_qc_service/__init__.py,sha256=OaL9dyyI6B8uRjopTIoD1zcX_H-SbGj46ZM-V-aoq6w,88
856
856
  cg/services/sequencing_qc_service/quality_checks/checks.py,sha256=qdcHRwZD7uxrOmacyiAG4-EN6nG5z-r4rLxcReU5kSI,2593
857
857
  cg/services/sequencing_qc_service/quality_checks/utils.py,sha256=2WN7S4kYsN_9iYPx7d4coAYcWHeueQWrPP2pJ8ztMMc,8969
858
- cg/services/sequencing_qc_service/sequencing_qc_service.py,sha256=2QIJ9IDZeMtO74ZHJ9bfzyK3-RhDK-m9xaoKsi9RHt8,1969
858
+ cg/services/sequencing_qc_service/sequencing_qc_service.py,sha256=QQHShCiq-OAobzHnTKQ1buQVyDIqGbVEPyPM4WEV9B0,2257
859
859
  cg/services/sequencing_qc_service/utils.py,sha256=5WHJltBICfRODEzFVPFTdCbGNaMKCaVeOswHgIOGgFc,199
860
860
  cg/services/slurm_service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
861
861
  cg/services/slurm_service/slurm_cli_service.py,sha256=t-XZoAOPgL-eufwK0A6H8WJvGtfWnlIYxnvKZJIX5-Y,702
@@ -923,7 +923,7 @@ cg/utils/flask/enum.py,sha256=xwNVtFPkSzoloJctLHu7obRyxcng1GJrhkeYkqwf9tw,1052
923
923
  cg/utils/mapping.py,sha256=oZpZW2kgsbtAP2FZ7RtRPELiEE1zZk_nAGisHGtCOUo,491
924
924
  cg/utils/time.py,sha256=_VOglhrFEZ5cwHK1U1g36SdwzB7UvV-Nvlt4ymuZUho,1501
925
925
  cg/utils/utils.py,sha256=RciI_UhWcnG_pMZrmQZ1ZYb-O1N0DweTYMmhE0SIRgQ,1410
926
- cg-83.15.0.dist-info/METADATA,sha256=wj51NyMN6wmwfhFYzc6eCNr6yc2UzVNWHh5V_r30Vgs,4940
927
- cg-83.15.0.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
928
- cg-83.15.0.dist-info/entry_points.txt,sha256=q5f47YQQGltzK_xnIq1mDopRXXEItr85Xe1BCtG-Wts,39
929
- cg-83.15.0.dist-info/RECORD,,
926
+ cg-83.15.2.dist-info/METADATA,sha256=auXlXIG1QVGKCp6xq7jKsHnieLTQ406wudFiN1HSVww,4940
927
+ cg-83.15.2.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
928
+ cg-83.15.2.dist-info/entry_points.txt,sha256=q5f47YQQGltzK_xnIq1mDopRXXEItr85Xe1BCtG-Wts,39
929
+ cg-83.15.2.dist-info/RECORD,,
File without changes