cg 80.1.0__py3-none-any.whl → 83.14.0__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 +1 -1
- cg/apps/housekeeper/hk.py +1 -1
- cg/apps/tb/api.py +1 -1
- cg/cli/upload/mutacc.py +16 -3
- cg/cli/upload/scout.py +2 -2
- cg/cli/upload/utils.py +10 -1
- cg/cli/workflow/balsamic/base.py +29 -4
- cg/cli/workflow/microsalt/base.py +3 -1
- cg/cli/workflow/nallo/base.py +18 -38
- cg/cli/workflow/nf_analysis.py +2 -203
- cg/cli/workflow/raredisease/base.py +33 -51
- cg/cli/workflow/rnafusion/base.py +28 -3
- cg/cli/workflow/taxprofiler/base.py +21 -13
- cg/cli/workflow/tomte/base.py +17 -19
- cg/constants/constants.py +3 -3
- cg/constants/devices.py +6 -1
- cg/constants/gene_panel.py +3 -1
- cg/constants/lims.py +4 -0
- cg/constants/orderforms.py +1 -1
- cg/constants/pacbio.py +1 -0
- cg/constants/scout.py +6 -4
- cg/exc.py +12 -4
- cg/meta/compress/compress.py +7 -2
- cg/meta/delivery_report/nallo.py +1 -1
- cg/meta/delivery_report/templates/macros/ticket_system.html +1 -1
- cg/meta/observations/balsamic_observations_api.py +1 -1
- cg/meta/observations/mip_dna_observations_api.py +1 -1
- cg/meta/observations/nallo_observations_api.py +1 -1
- cg/meta/observations/observations_api.py +1 -1
- cg/meta/observations/raredisease_observations_api.py +1 -1
- cg/meta/tar/tar.py +5 -2
- cg/meta/upload/coverage.py +5 -5
- cg/meta/upload/raredisease/raredisease.py +3 -0
- cg/meta/upload/scout/nallo_config_builder.py +14 -0
- cg/meta/workflow/nallo.py +22 -95
- cg/meta/workflow/nf_analysis.py +11 -262
- cg/meta/workflow/raredisease.py +3 -112
- cg/meta/workflow/rnafusion.py +2 -34
- cg/meta/workflow/taxprofiler.py +2 -38
- cg/meta/workflow/tomte.py +2 -42
- cg/models/deliverables/metric_deliverables.py +1 -1
- cg/models/nallo/nallo.py +14 -64
- cg/models/nf_analysis.py +1 -41
- cg/models/raredisease/raredisease.py +0 -62
- cg/models/rnafusion/rnafusion.py +0 -26
- cg/models/scout/scout_load_config.py +1 -0
- cg/models/taxprofiler/taxprofiler.py +0 -42
- cg/models/tomte/tomte.py +0 -69
- cg/resources/nallo_bundle_filenames.yaml +282 -22
- cg/resources/raredisease_bundle_filenames.yaml +11 -1
- cg/resources/taxprofiler_bundle_filenames.yaml +20 -0
- cg/server/admin.py +51 -24
- cg/server/app.py +15 -4
- cg/server/endpoints/sequencing_run/dtos.py +21 -3
- cg/server/endpoints/sequencing_run/pacbio_sequencing_run.py +29 -10
- cg/server/endpoints/sequencing_run/pacbio_smrt_cell_metrics.py +20 -0
- cg/services/analysis_starter/configurator/configurator.py +1 -1
- cg/services/analysis_starter/configurator/file_creators/nextflow/params_file/models.py +40 -1
- cg/services/analysis_starter/configurator/file_creators/nextflow/params_file/nallo.py +3 -1
- cg/services/analysis_starter/configurator/file_creators/nextflow/params_file/tomte_params_file_creator.py +3 -1
- cg/services/analysis_starter/factories/configurator_factory.py +4 -4
- cg/services/analysis_starter/tracker/implementations/balsamic.py +4 -1
- cg/services/analysis_starter/tracker/implementations/microsalt.py +4 -4
- cg/services/analysis_starter/tracker/implementations/mip_dna.py +4 -1
- cg/services/analysis_starter/tracker/implementations/nextflow_tracker.py +6 -4
- cg/services/analysis_starter/tracker/tracker.py +10 -6
- cg/services/illumina/backup/backup_service.py +29 -7
- cg/services/orders/validation/constants.py +3 -0
- cg/services/orders/validation/index_sequences.py +558 -0
- cg/services/run_devices/pacbio/data_storage_service/pacbio_store_service.py +39 -18
- cg/services/run_devices/pacbio/data_transfer_service/data_transfer_service.py +8 -2
- cg/services/run_devices/pacbio/data_transfer_service/dto.py +9 -3
- cg/services/run_devices/pacbio/data_transfer_service/utils.py +14 -7
- cg/services/run_devices/pacbio/metrics_parser/models.py +1 -0
- cg/services/run_devices/pacbio/sequencing_runs_service.py +35 -7
- cg/services/sequencing_qc_service/quality_checks/checks.py +18 -16
- cg/services/sequencing_qc_service/quality_checks/utils.py +82 -18
- cg/services/sequencing_qc_service/sequencing_qc_service.py +12 -10
- cg/store/crud/create.py +73 -42
- cg/store/crud/read.py +50 -2
- cg/store/crud/update.py +14 -3
- cg/store/models.py +88 -31
- cg/store/store.py +8 -1
- {cg-80.1.0.dist-info → cg-83.14.0.dist-info}/METADATA +1 -1
- {cg-80.1.0.dist-info → cg-83.14.0.dist-info}/RECORD +91 -90
- /cg/services/analysis_starter/configurator/file_creators/nextflow/sample_sheet/{nallo.py → nallo_sample_sheet_creator.py} +0 -0
- /cg/services/analysis_starter/configurator/file_creators/nextflow/sample_sheet/{raredisease.py → raredisease_sample_sheet_creator.py} +0 -0
- /cg/services/analysis_starter/configurator/file_creators/nextflow/sample_sheet/{rnafusion.py → rnafusion_sample_sheet_creator.py} +0 -0
- /cg/services/analysis_starter/configurator/file_creators/nextflow/sample_sheet/{taxprofiler.py → taxprofiler_sample_sheet_creator.py} +0 -0
- {cg-80.1.0.dist-info → cg-83.14.0.dist-info}/WHEEL +0 -0
- {cg-80.1.0.dist-info → cg-83.14.0.dist-info}/entry_points.txt +0 -0
|
@@ -3,7 +3,7 @@ from datetime import datetime
|
|
|
3
3
|
from pydantic import BaseModel
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
class
|
|
6
|
+
class PacbioSmrtCellMetricsDTO(BaseModel):
|
|
7
7
|
barcoded_hifi_mean_read_length: int
|
|
8
8
|
barcoded_hifi_reads: int
|
|
9
9
|
barcoded_hifi_reads_percentage: float
|
|
@@ -24,5 +24,23 @@ class PacbioSequencingRunDTO(BaseModel):
|
|
|
24
24
|
well: str
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
class
|
|
28
|
-
runs: list[
|
|
27
|
+
class PacbioSmrtCellMetricsResponse(BaseModel):
|
|
28
|
+
runs: list[PacbioSmrtCellMetricsDTO]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class PacbioSequencingRunDTO(BaseModel):
|
|
32
|
+
id: int
|
|
33
|
+
run_name: str
|
|
34
|
+
comment: str
|
|
35
|
+
processed: bool
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class PacbioSequencingRunResponse(BaseModel):
|
|
39
|
+
pacbio_sequencing_runs: list[PacbioSequencingRunDTO]
|
|
40
|
+
total_count: int
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class PacbioSequencingRunUpdateRequest(BaseModel):
|
|
44
|
+
id: int
|
|
45
|
+
comment: str | None = None
|
|
46
|
+
processed: bool | None = None
|
|
@@ -1,20 +1,39 @@
|
|
|
1
|
-
from
|
|
1
|
+
from http import HTTPStatus
|
|
2
|
+
|
|
3
|
+
from flask import Blueprint, Response, jsonify, request
|
|
4
|
+
from pydantic import ValidationError
|
|
2
5
|
|
|
3
6
|
from cg.server.endpoints.error_handler import handle_missing_entries
|
|
4
|
-
from cg.server.endpoints.sequencing_run.dtos import
|
|
7
|
+
from cg.server.endpoints.sequencing_run.dtos import (
|
|
8
|
+
PacbioSequencingRunResponse,
|
|
9
|
+
PacbioSequencingRunUpdateRequest,
|
|
10
|
+
)
|
|
5
11
|
from cg.server.endpoints.utils import before_request
|
|
6
12
|
from cg.server.ext import pacbio_sequencing_runs_service
|
|
7
13
|
|
|
8
|
-
|
|
9
|
-
"
|
|
14
|
+
PACBIO_SEQUENCING_RUNS_BLUEPRINT = Blueprint(
|
|
15
|
+
"pacbio_sequencing_runs", __name__, url_prefix="/api/v1/"
|
|
10
16
|
)
|
|
11
|
-
|
|
17
|
+
PACBIO_SEQUENCING_RUNS_BLUEPRINT.before_request(before_request)
|
|
12
18
|
|
|
13
19
|
|
|
14
|
-
@
|
|
20
|
+
@PACBIO_SEQUENCING_RUNS_BLUEPRINT.route("/pacbio_sequencing_runs", methods=["GET"])
|
|
15
21
|
@handle_missing_entries
|
|
16
|
-
def get_sequencing_runs(
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
def get_sequencing_runs():
|
|
23
|
+
page: int = int(request.args.get("page", "0"))
|
|
24
|
+
page_size: int = int(request.args.get("pageSize", "0"))
|
|
25
|
+
sequencing_runs: PacbioSequencingRunResponse = (
|
|
26
|
+
pacbio_sequencing_runs_service.get_sequencing_runs(page=page, page_size=page_size)
|
|
19
27
|
)
|
|
20
|
-
return jsonify(
|
|
28
|
+
return jsonify(sequencing_runs.model_dump())
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@PACBIO_SEQUENCING_RUNS_BLUEPRINT.route("/pacbio_sequencing_runs/<id>", methods=["PATCH"])
|
|
32
|
+
@handle_missing_entries
|
|
33
|
+
def update_sequencing_run(id: str):
|
|
34
|
+
try:
|
|
35
|
+
update_request = PacbioSequencingRunUpdateRequest(id=id, **request.json)
|
|
36
|
+
except ValidationError:
|
|
37
|
+
return Response(status=HTTPStatus.UNPROCESSABLE_ENTITY)
|
|
38
|
+
pacbio_sequencing_runs_service.update_sequencing_run(update_request=update_request)
|
|
39
|
+
return Response(status=HTTPStatus.NO_CONTENT)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from flask import Blueprint, jsonify
|
|
2
|
+
|
|
3
|
+
from cg.server.endpoints.error_handler import handle_missing_entries
|
|
4
|
+
from cg.server.endpoints.sequencing_run.dtos import PacbioSmrtCellMetricsResponse
|
|
5
|
+
from cg.server.endpoints.utils import before_request
|
|
6
|
+
from cg.server.ext import pacbio_sequencing_runs_service
|
|
7
|
+
|
|
8
|
+
PACBIO_SMRT_CELL_METRICS_BLUEPRINT = Blueprint(
|
|
9
|
+
"pacbio_smrt_cell_metrics", __name__, url_prefix="/api/v1/pacbio_smrt_cell_metrics"
|
|
10
|
+
)
|
|
11
|
+
PACBIO_SMRT_CELL_METRICS_BLUEPRINT.before_request(before_request)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@PACBIO_SMRT_CELL_METRICS_BLUEPRINT.route("/<run_name>", methods=["GET"])
|
|
15
|
+
@handle_missing_entries
|
|
16
|
+
def get_smrt_cell_metrics(run_name: str):
|
|
17
|
+
response: PacbioSmrtCellMetricsResponse = (
|
|
18
|
+
pacbio_sequencing_runs_service.get_sequencing_runs_by_name(run_name)
|
|
19
|
+
)
|
|
20
|
+
return jsonify(response.model_dump())
|
|
@@ -20,7 +20,7 @@ class Configurator(ABC):
|
|
|
20
20
|
@staticmethod
|
|
21
21
|
def _set_flags(config: SpecificCaseConfig, **flags) -> SpecificCaseConfig:
|
|
22
22
|
curated_flags: dict = {key: value for key, value in flags.items() if value is not None}
|
|
23
|
-
return config.
|
|
23
|
+
return config.model_validate(config.model_dump(by_alias=True) | curated_flags)
|
|
24
24
|
|
|
25
25
|
@abstractmethod
|
|
26
26
|
def _ensure_required_config_files_exist(self, **kwargs) -> None:
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from pydantic import BaseModel, field_validator
|
|
4
|
+
|
|
5
|
+
from cg.constants.constants import GenomeVersion
|
|
6
|
+
from cg.constants.sample_sources import SourceType
|
|
7
|
+
from cg.utils.utils import replace_non_alphanumeric
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class WorkflowParameters(BaseModel):
|
|
11
|
+
input: Path
|
|
12
|
+
outdir: Path
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class NalloParameters(WorkflowParameters):
|
|
16
|
+
"""Model for Nallo parameters."""
|
|
17
|
+
|
|
18
|
+
filter_variants_hgnc_ids: str
|
|
4
19
|
|
|
5
20
|
|
|
6
21
|
class RarediseaseParameters(WorkflowParameters):
|
|
@@ -20,3 +35,27 @@ class RNAFusionParameters(WorkflowParameters):
|
|
|
20
35
|
|
|
21
36
|
class TaxprofilerParameters(WorkflowParameters):
|
|
22
37
|
"""Taxprofiler parameters."""
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class TomteParameters(WorkflowParameters):
|
|
41
|
+
"""Model for Tomte parameters."""
|
|
42
|
+
|
|
43
|
+
gene_panel_clinical_filter: Path
|
|
44
|
+
tissue: str
|
|
45
|
+
genome: str = GenomeVersion.HG38
|
|
46
|
+
|
|
47
|
+
@field_validator("tissue", mode="before")
|
|
48
|
+
@classmethod
|
|
49
|
+
def restrict_tissue_values(cls, tissue: str | None) -> str:
|
|
50
|
+
if tissue:
|
|
51
|
+
return replace_non_alphanumeric(string=tissue)
|
|
52
|
+
else:
|
|
53
|
+
return SourceType.UNKNOWN
|
|
54
|
+
|
|
55
|
+
@field_validator("genome", mode="before")
|
|
56
|
+
@classmethod
|
|
57
|
+
def restrict_genome_values(cls, genome: str) -> str:
|
|
58
|
+
if genome == GenomeVersion.HG38:
|
|
59
|
+
return GenomeVersion.GRCh38.value
|
|
60
|
+
elif genome == GenomeVersion.HG19:
|
|
61
|
+
return GenomeVersion.GRCh37.value
|
|
@@ -4,10 +4,12 @@ from typing import Any
|
|
|
4
4
|
|
|
5
5
|
from cg.constants.scout import ScoutExportFileName
|
|
6
6
|
from cg.io.yaml import read_yaml, write_yaml_nextflow_style
|
|
7
|
-
from cg.models.nallo.nallo import NalloParameters
|
|
8
7
|
from cg.services.analysis_starter.configurator.file_creators.nextflow.params_file.abstract import (
|
|
9
8
|
ParamsFileCreator,
|
|
10
9
|
)
|
|
10
|
+
from cg.services.analysis_starter.configurator.file_creators.nextflow.params_file.models import (
|
|
11
|
+
NalloParameters,
|
|
12
|
+
)
|
|
11
13
|
from cg.services.analysis_starter.configurator.file_creators.nextflow.params_file.utils import (
|
|
12
14
|
replace_values_in_params_file,
|
|
13
15
|
)
|
|
@@ -6,10 +6,12 @@ from cg.constants.constants import GenomeVersion
|
|
|
6
6
|
from cg.constants.scout import ScoutExportFileName
|
|
7
7
|
from cg.exc import CgError
|
|
8
8
|
from cg.io.yaml import read_yaml, write_yaml_nextflow_style
|
|
9
|
-
from cg.models.tomte.tomte import TomteParameters
|
|
10
9
|
from cg.services.analysis_starter.configurator.file_creators.nextflow.params_file.abstract import (
|
|
11
10
|
ParamsFileCreator,
|
|
12
11
|
)
|
|
12
|
+
from cg.services.analysis_starter.configurator.file_creators.nextflow.params_file.models import (
|
|
13
|
+
TomteParameters,
|
|
14
|
+
)
|
|
13
15
|
from cg.services.analysis_starter.configurator.file_creators.nextflow.params_file.utils import (
|
|
14
16
|
replace_values_in_params_file,
|
|
15
17
|
)
|
|
@@ -47,19 +47,19 @@ from cg.services.analysis_starter.configurator.file_creators.nextflow.params_fil
|
|
|
47
47
|
from cg.services.analysis_starter.configurator.file_creators.nextflow.params_file.tomte_params_file_creator import (
|
|
48
48
|
TomteParamsFileCreator,
|
|
49
49
|
)
|
|
50
|
-
from cg.services.analysis_starter.configurator.file_creators.nextflow.sample_sheet.
|
|
50
|
+
from cg.services.analysis_starter.configurator.file_creators.nextflow.sample_sheet.nallo_sample_sheet_creator import (
|
|
51
51
|
NalloSampleSheetCreator,
|
|
52
52
|
)
|
|
53
53
|
from cg.services.analysis_starter.configurator.file_creators.nextflow.sample_sheet.protocol import (
|
|
54
54
|
SampleSheetCreator,
|
|
55
55
|
)
|
|
56
|
-
from cg.services.analysis_starter.configurator.file_creators.nextflow.sample_sheet.
|
|
56
|
+
from cg.services.analysis_starter.configurator.file_creators.nextflow.sample_sheet.raredisease_sample_sheet_creator import (
|
|
57
57
|
RarediseaseSampleSheetCreator,
|
|
58
58
|
)
|
|
59
|
-
from cg.services.analysis_starter.configurator.file_creators.nextflow.sample_sheet.
|
|
59
|
+
from cg.services.analysis_starter.configurator.file_creators.nextflow.sample_sheet.rnafusion_sample_sheet_creator import (
|
|
60
60
|
RNAFusionSampleSheetCreator,
|
|
61
61
|
)
|
|
62
|
-
from cg.services.analysis_starter.configurator.file_creators.nextflow.sample_sheet.
|
|
62
|
+
from cg.services.analysis_starter.configurator.file_creators.nextflow.sample_sheet.taxprofiler_sample_sheet_creator import (
|
|
63
63
|
TaxprofilerSampleSheetCreator,
|
|
64
64
|
)
|
|
65
65
|
from cg.services.analysis_starter.configurator.file_creators.nextflow.sample_sheet.tomte_sample_sheet_creator import (
|
|
@@ -12,7 +12,10 @@ class BalsamicTracker(Tracker):
|
|
|
12
12
|
return WorkflowManager.Slurm
|
|
13
13
|
|
|
14
14
|
def _get_job_ids_path(self, case_id: str) -> Path:
|
|
15
|
-
return Path(self.
|
|
15
|
+
return Path(self._get_out_dir_path(case_id), "slurm_jobids.yaml")
|
|
16
|
+
|
|
17
|
+
def _get_out_dir_path(self, case_id: str) -> Path:
|
|
18
|
+
return Path(self.workflow_root, case_id, "analysis")
|
|
16
19
|
|
|
17
20
|
def _get_workflow_version(self, case_config: BalsamicCaseConfig) -> str:
|
|
18
21
|
config_data: dict = read_json(case_config.sample_config)
|
|
@@ -27,13 +27,13 @@ class MicrosaltTracker(Tracker):
|
|
|
27
27
|
def _get_job_ids_path(self, case_id: str) -> Path:
|
|
28
28
|
project_id: str = self._get_file_name_start(case_id)
|
|
29
29
|
return Path(
|
|
30
|
-
self.
|
|
31
|
-
"results",
|
|
32
|
-
"reports",
|
|
33
|
-
"trailblazer",
|
|
30
|
+
self._get_out_dir_path(case_id),
|
|
34
31
|
f"{project_id}_slurm_ids{FileExtensions.YAML}",
|
|
35
32
|
)
|
|
36
33
|
|
|
34
|
+
def _get_out_dir_path(self, case_id: str) -> Path:
|
|
35
|
+
return Path(self.workflow_root, "results", "reports", "trailblazer")
|
|
36
|
+
|
|
37
37
|
def _get_file_name_start(self, case_id: str) -> str:
|
|
38
38
|
"""Returns the LIMS project id if the case contains multiple samples, else the sample id."""
|
|
39
39
|
case: Case = self.store.get_case_by_internal_id(case_id)
|
|
@@ -12,7 +12,10 @@ class MIPDNATracker(Tracker):
|
|
|
12
12
|
return WorkflowManager.Slurm
|
|
13
13
|
|
|
14
14
|
def _get_job_ids_path(self, case_id: str) -> Path:
|
|
15
|
-
return Path(self.
|
|
15
|
+
return Path(self._get_out_dir_path(case_id), "slurm_job_ids.yaml")
|
|
16
|
+
|
|
17
|
+
def _get_out_dir_path(self, case_id: str) -> Path:
|
|
18
|
+
return Path(self.workflow_root, case_id, "analysis")
|
|
16
19
|
|
|
17
20
|
def _get_sample_info_path(self, case_id: str) -> Path:
|
|
18
21
|
return Path(self.workflow_root, case_id, "analysis", f"{case_id}_qc_sample_info.yaml")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
|
-
from cg.constants.constants import
|
|
3
|
+
from cg.constants.constants import WorkflowManager
|
|
4
4
|
from cg.services.analysis_starter.configurator.models.nextflow import NextflowCaseConfig
|
|
5
5
|
from cg.services.analysis_starter.tracker.tracker import Tracker
|
|
6
6
|
|
|
@@ -9,9 +9,11 @@ class NextflowTracker(Tracker):
|
|
|
9
9
|
def _workflow_manager(self) -> WorkflowManager:
|
|
10
10
|
return WorkflowManager.Tower
|
|
11
11
|
|
|
12
|
-
def _get_job_ids_path(self, case_id: str) -> Path:
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
def _get_job_ids_path(self, case_id: str) -> Path | None:
|
|
13
|
+
return None
|
|
14
|
+
|
|
15
|
+
def _get_out_dir_path(self, case_id: str) -> Path:
|
|
16
|
+
return Path(self.workflow_root, case_id)
|
|
15
17
|
|
|
16
18
|
def _get_workflow_version(self, case_config: NextflowCaseConfig) -> str:
|
|
17
19
|
return case_config.revision
|
|
@@ -6,7 +6,7 @@ from pathlib import Path
|
|
|
6
6
|
from cg.apps.environ import environ_email
|
|
7
7
|
from cg.apps.tb import TrailblazerAPI
|
|
8
8
|
from cg.apps.tb.models import TrailblazerAnalysis
|
|
9
|
-
from cg.constants.constants import CaseActions, CustomerId, Workflow
|
|
9
|
+
from cg.constants.constants import CaseActions, CustomerId, Workflow, WorkflowManager
|
|
10
10
|
from cg.constants.priority import TrailblazerPriority
|
|
11
11
|
from cg.constants.sequencing import SeqLibraryPrepCategory
|
|
12
12
|
from cg.constants.tb import AnalysisType
|
|
@@ -61,17 +61,17 @@ class Tracker(ABC):
|
|
|
61
61
|
self, case_id: str, tower_workflow_id: str | None
|
|
62
62
|
) -> TrailblazerAnalysis:
|
|
63
63
|
analysis_type: str = self._get_analysis_type(case_id)
|
|
64
|
-
config_path: Path = self._get_job_ids_path(case_id)
|
|
64
|
+
config_path: Path | None = self._get_job_ids_path(case_id)
|
|
65
65
|
email: str = environ_email()
|
|
66
66
|
order_id: int = self.store.get_case_by_internal_id_strict(case_id).latest_order.id
|
|
67
|
-
out_dir: str =
|
|
67
|
+
out_dir: str = self._get_out_dir_path(case_id).as_posix()
|
|
68
68
|
priority: TrailblazerPriority = self._get_trailblazer_priority(case_id)
|
|
69
69
|
ticket: str = self.store.get_latest_ticket_from_case(case_id)
|
|
70
70
|
is_case_for_development: bool = self._is_case_for_development(case_id)
|
|
71
71
|
return self.trailblazer_api.add_pending_analysis(
|
|
72
72
|
analysis_type=analysis_type,
|
|
73
73
|
case_id=case_id,
|
|
74
|
-
config_path=config_path.as_posix(),
|
|
74
|
+
config_path=config_path.as_posix() if config_path else None,
|
|
75
75
|
email=email,
|
|
76
76
|
order_id=order_id,
|
|
77
77
|
out_dir=out_dir,
|
|
@@ -133,11 +133,15 @@ class Tracker(ABC):
|
|
|
133
133
|
return case.customer.internal_id == CustomerId.CG_INTERNAL_CUSTOMER
|
|
134
134
|
|
|
135
135
|
@abstractmethod
|
|
136
|
-
def _workflow_manager(self):
|
|
136
|
+
def _workflow_manager(self) -> WorkflowManager:
|
|
137
137
|
pass
|
|
138
138
|
|
|
139
139
|
@abstractmethod
|
|
140
|
-
def _get_job_ids_path(self, case_id: str):
|
|
140
|
+
def _get_job_ids_path(self, case_id: str) -> Path | None:
|
|
141
|
+
pass
|
|
142
|
+
|
|
143
|
+
@abstractmethod
|
|
144
|
+
def _get_out_dir_path(self, case_id: str) -> Path:
|
|
141
145
|
pass
|
|
142
146
|
|
|
143
147
|
@abstractmethod
|
|
@@ -114,7 +114,10 @@ class IlluminaBackupService:
|
|
|
114
114
|
"""Process a flow cell from backup. Return elapsed time."""
|
|
115
115
|
start_time: float = get_start_time()
|
|
116
116
|
run_dir = Path(self.sequencing_runs_dir)
|
|
117
|
-
|
|
117
|
+
is_current: bool = self._is_archiving_directory_current(archived_run)
|
|
118
|
+
sequencing_run_output_dir: Path = self._get_sequencing_run_output_dir(
|
|
119
|
+
archived_run=archived_run, is_current=is_current
|
|
120
|
+
)
|
|
118
121
|
self.retrieve_archived_key(
|
|
119
122
|
archived_key=archived_key, sequencing_run=sequencing_run, run_dir=run_dir
|
|
120
123
|
)
|
|
@@ -128,9 +131,12 @@ class IlluminaBackupService:
|
|
|
128
131
|
encryption_key,
|
|
129
132
|
retrieved_run,
|
|
130
133
|
retrieved_key,
|
|
131
|
-
) = self.decrypt_sequencing_run(
|
|
132
|
-
|
|
133
|
-
|
|
134
|
+
) = self.decrypt_sequencing_run(
|
|
135
|
+
archived_run=archived_run, archived_key=archived_key, run_dir=run_dir
|
|
136
|
+
)
|
|
137
|
+
self.extract_sequencing_run(
|
|
138
|
+
decrypted_run=decrypted_run, is_current=is_current, run_dir=run_dir
|
|
139
|
+
)
|
|
134
140
|
self.create_rta_complete(sequencing_run_output_dir)
|
|
135
141
|
self.create_copy_complete(sequencing_run_output_dir)
|
|
136
142
|
self.unlink_files(decrypted_run, encryption_key, retrieved_run, retrieved_key)
|
|
@@ -145,6 +151,20 @@ class IlluminaBackupService:
|
|
|
145
151
|
|
|
146
152
|
return get_elapsed_time(start_time=start_time)
|
|
147
153
|
|
|
154
|
+
def _get_sequencing_run_output_dir(self, archived_run: Path, is_current: bool) -> Path:
|
|
155
|
+
"""Return the path to the sequencing run based on the archived run path."""
|
|
156
|
+
if is_current:
|
|
157
|
+
run_full_name: str = archived_run.parent.name
|
|
158
|
+
else:
|
|
159
|
+
run_full_name: str = archived_run.name.split(".")[0]
|
|
160
|
+
return Path(self.sequencing_runs_dir, run_full_name)
|
|
161
|
+
|
|
162
|
+
def _is_archiving_directory_current(self, archived_run: Path) -> bool:
|
|
163
|
+
"""Check if the archived run is in the current archiving directory."""
|
|
164
|
+
return archived_run.as_posix().startswith(
|
|
165
|
+
Path(self.pdc_archiving_directory.current).parent.as_posix()
|
|
166
|
+
)
|
|
167
|
+
|
|
148
168
|
def unlink_files(
|
|
149
169
|
self,
|
|
150
170
|
decrypted_run: Path,
|
|
@@ -184,10 +204,12 @@ class IlluminaBackupService:
|
|
|
184
204
|
"""Create a CopyComplete.txt file in the flow cell run directory."""
|
|
185
205
|
Path(flow_cell_directory, DemultiplexingDirsAndFiles.COPY_COMPLETE).touch()
|
|
186
206
|
|
|
187
|
-
def extract_sequencing_run(self, decrypted_run, run_dir):
|
|
207
|
+
def extract_sequencing_run(self, decrypted_run: Path, is_current: bool, run_dir: Path) -> None:
|
|
188
208
|
"""Extract the sequencing run tar archive."""
|
|
189
|
-
extraction_command = self.tar_api.get_extract_file_command(
|
|
190
|
-
input_file=decrypted_run,
|
|
209
|
+
extraction_command: list[str] = self.tar_api.get_extract_file_command(
|
|
210
|
+
input_file=decrypted_run,
|
|
211
|
+
output_dir=run_dir,
|
|
212
|
+
is_current=is_current,
|
|
191
213
|
)
|
|
192
214
|
LOG.debug(f"Extract sequencing run command: {extraction_command}")
|
|
193
215
|
self.tar_api.run_tar_command(extraction_command)
|
|
@@ -30,6 +30,7 @@ class ExtractionMethod(StrEnum):
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class IndexEnum(StrEnum):
|
|
33
|
+
ARCHER_SET_B = "Archer Set B"
|
|
33
34
|
AVIDA_INDEX_PLATE = "Avida Index plate"
|
|
34
35
|
AVIDA_INDEX_STRIP = "Avida Index strip"
|
|
35
36
|
IDT_DS_B = "IDT DupSeq 10 bp Set B"
|
|
@@ -37,6 +38,7 @@ class IndexEnum(StrEnum):
|
|
|
37
38
|
IDT_XGEN_UDI = "IDT xGen UDI Adapters"
|
|
38
39
|
IDT10_UDI_NIPT = "IDT10 UDI NIPT"
|
|
39
40
|
KAPA_UDI_NIPT = "KAPA UDI NIPT"
|
|
41
|
+
NEBNEXT_LV_Unique_Dual_2A = "NEBNext LV Unique Dual Index Primers Set 2A"
|
|
40
42
|
NEXTERA_XT = "Nextera XT Dual"
|
|
41
43
|
NEXTFLEX_UDI_96 = "NEXTflex® Unique Dual Index Barcodes 1 - 96"
|
|
42
44
|
NEXTFLEX_V2_UDI_96 = "NEXTflex® v2 UDI Barcodes 1 - 96"
|
|
@@ -46,4 +48,5 @@ class IndexEnum(StrEnum):
|
|
|
46
48
|
TWIST_UDI_B = "TWIST UDI Set B"
|
|
47
49
|
TWIST_UDI_C = "TWIST UDI Set C"
|
|
48
50
|
TRUSEQ_DNA_HT = "TruSeq DNA HT Dual-index (D7-D5)"
|
|
51
|
+
XGEN_UDI_10_1_4 = "xGen UDI 10nt Primer Plates 1-4"
|
|
49
52
|
NO_INDEX = "NoIndex"
|