cg 83.13.3__py3-none-any.whl → 83.15.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/exc.py +4 -0
- cg/services/sequencing_qc_service/quality_checks/checks.py +20 -16
- cg/services/sequencing_qc_service/quality_checks/utils.py +108 -18
- cg/services/sequencing_qc_service/sequencing_qc_service.py +12 -10
- cg/store/models.py +18 -2
- {cg-83.13.3.dist-info → cg-83.15.0.dist-info}/METADATA +1 -1
- {cg-83.13.3.dist-info → cg-83.15.0.dist-info}/RECORD +10 -10
- {cg-83.13.3.dist-info → cg-83.15.0.dist-info}/WHEEL +1 -1
- {cg-83.13.3.dist-info → cg-83.15.0.dist-info}/entry_points.txt +0 -0
cg/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
__title__ = "cg"
|
|
2
|
-
__version__ = "83.
|
|
2
|
+
__version__ = "83.15.0"
|
cg/exc.py
CHANGED
|
@@ -354,3 +354,7 @@ class MissingConfigFilesError(CgError):
|
|
|
354
354
|
|
|
355
355
|
class SeqeraError(CgError):
|
|
356
356
|
"""Exception raised when receiving an unexpected response from Seqera platform"""
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
class ApplicationDoesNotHaveHiFiYieldError(CgError):
|
|
360
|
+
"""Exception raised when application does not have HiFi yield set."""
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
1
2
|
from enum import Enum
|
|
2
|
-
from typing import Callable
|
|
3
3
|
|
|
4
4
|
from cg.constants import Workflow
|
|
5
5
|
from cg.services.sequencing_qc_service.quality_checks.utils import (
|
|
6
6
|
all_samples_in_case_have_reads,
|
|
7
7
|
any_sample_in_case_has_reads,
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
case_pass_sequencing_qc_on_hifi_yield,
|
|
9
|
+
case_pass_sequencing_qc_on_reads,
|
|
10
|
+
raw_data_case_pass_qc,
|
|
11
|
+
sample_pass_sequencing_qc_on_reads,
|
|
10
12
|
)
|
|
11
13
|
from cg.store.models import Case
|
|
12
14
|
|
|
@@ -18,10 +20,12 @@ class QualityCheck(Enum):
|
|
|
18
20
|
|
|
19
21
|
|
|
20
22
|
class SequencingQCCheck(QualityCheck):
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
CASE_PASSES_ON_READS: Callable = case_pass_sequencing_qc_on_reads
|
|
24
|
+
CASE_PASSES_ON_YIELD: Callable = case_pass_sequencing_qc_on_hifi_yield
|
|
25
|
+
SAMPLE_PASSES: Callable = sample_pass_sequencing_qc_on_reads
|
|
23
26
|
ALL_SAMPLES_IN_CASE_HAVE_READS: Callable = all_samples_in_case_have_reads
|
|
24
27
|
ANY_SAMPLE_IN_CASE_HAS_READS: Callable = any_sample_in_case_has_reads
|
|
28
|
+
RAW_DATA_CASE_QC: Callable = raw_data_case_pass_qc
|
|
25
29
|
|
|
26
30
|
|
|
27
31
|
def get_sequencing_quality_check_for_case(case: Case) -> Callable:
|
|
@@ -29,20 +33,20 @@ def get_sequencing_quality_check_for_case(case: Case) -> Callable:
|
|
|
29
33
|
workflow: Workflow = case.data_analysis
|
|
30
34
|
|
|
31
35
|
workflow_qc_mapping = {
|
|
32
|
-
Workflow.BALSAMIC: SequencingQCCheck.
|
|
33
|
-
Workflow.BALSAMIC_PON: SequencingQCCheck.
|
|
34
|
-
Workflow.BALSAMIC_UMI: SequencingQCCheck.
|
|
35
|
-
Workflow.MIP_DNA: SequencingQCCheck.CASE_PASSES,
|
|
36
|
-
Workflow.MIP_RNA: SequencingQCCheck.CASE_PASSES,
|
|
37
|
-
Workflow.RAREDISEASE: SequencingQCCheck.CASE_PASSES,
|
|
38
|
-
Workflow.RNAFUSION: SequencingQCCheck.CASE_PASSES,
|
|
39
|
-
Workflow.TOMTE: SequencingQCCheck.CASE_PASSES,
|
|
36
|
+
Workflow.BALSAMIC: SequencingQCCheck.CASE_PASSES_ON_READS,
|
|
37
|
+
Workflow.BALSAMIC_PON: SequencingQCCheck.CASE_PASSES_ON_READS,
|
|
38
|
+
Workflow.BALSAMIC_UMI: SequencingQCCheck.CASE_PASSES_ON_READS,
|
|
40
39
|
Workflow.FLUFFY: SequencingQCCheck.ANY_SAMPLE_IN_CASE_HAS_READS,
|
|
41
|
-
Workflow.RAW_DATA: SequencingQCCheck.ANY_SAMPLE_IN_CASE_HAS_READS,
|
|
42
40
|
Workflow.MICROSALT: SequencingQCCheck.ANY_SAMPLE_IN_CASE_HAS_READS,
|
|
41
|
+
Workflow.MIP_DNA: SequencingQCCheck.CASE_PASSES_ON_READS,
|
|
42
|
+
Workflow.MIP_RNA: SequencingQCCheck.CASE_PASSES_ON_READS,
|
|
43
43
|
Workflow.MUTANT: SequencingQCCheck.ANY_SAMPLE_IN_CASE_HAS_READS,
|
|
44
|
+
Workflow.NALLO: SequencingQCCheck.CASE_PASSES_ON_YIELD,
|
|
45
|
+
Workflow.RAREDISEASE: SequencingQCCheck.CASE_PASSES_ON_READS,
|
|
46
|
+
Workflow.RAW_DATA: SequencingQCCheck.RAW_DATA_CASE_QC,
|
|
47
|
+
Workflow.RNAFUSION: SequencingQCCheck.CASE_PASSES_ON_READS,
|
|
44
48
|
Workflow.TAXPROFILER: SequencingQCCheck.ALL_SAMPLES_IN_CASE_HAVE_READS,
|
|
45
|
-
Workflow.
|
|
49
|
+
Workflow.TOMTE: SequencingQCCheck.CASE_PASSES_ON_READS,
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
if workflow in workflow_qc_mapping:
|
|
@@ -55,5 +59,5 @@ def get_sample_sequencing_quality_check() -> Callable:
|
|
|
55
59
|
return SequencingQCCheck.SAMPLE_PASSES
|
|
56
60
|
|
|
57
61
|
|
|
58
|
-
def run_quality_checks(quality_checks: list[
|
|
62
|
+
def run_quality_checks(quality_checks: list[Callable], **kwargs) -> bool:
|
|
59
63
|
return all(quality_check(**kwargs) for quality_check in quality_checks)
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
|
|
3
|
+
from cg.constants.devices import DeviceType
|
|
3
4
|
from cg.constants.priority import Priority
|
|
4
5
|
from cg.constants.sequencing import SeqLibraryPrepCategory
|
|
6
|
+
from cg.exc import ApplicationDoesNotHaveHiFiYieldError
|
|
5
7
|
from cg.store.models import Case, Sample
|
|
6
8
|
|
|
7
9
|
LOG = logging.getLogger(__name__)
|
|
8
10
|
|
|
9
11
|
|
|
10
|
-
def
|
|
12
|
+
def case_pass_sequencing_qc_on_reads(case: Case) -> bool:
|
|
11
13
|
"""
|
|
12
14
|
Get the sequencing QC of a case. The checks are performed in the following order:
|
|
13
15
|
1. If the case is a ready-made library, the ready made library QC is used.
|
|
@@ -21,22 +23,66 @@ def case_pass_sequencing_qc(case: Case) -> bool:
|
|
|
21
23
|
if is_case_ready_made_library(case):
|
|
22
24
|
return ready_made_library_case_pass_sequencing_qc(case)
|
|
23
25
|
if is_case_express_priority(case):
|
|
24
|
-
return
|
|
26
|
+
return express_case_pass_sequencing_qc_on_reads(case)
|
|
25
27
|
return all(sample_has_enough_reads(sample) for sample in case.samples)
|
|
26
28
|
|
|
27
29
|
|
|
28
|
-
def
|
|
30
|
+
def case_pass_sequencing_qc_on_hifi_yield(case: Case) -> bool:
|
|
31
|
+
"""
|
|
32
|
+
Get the sequencing QC of a case using yield. The checks are performed in the following order:
|
|
33
|
+
1. If the case is express priority, the express QC is used.
|
|
34
|
+
2. If the above condition is not met then it checks if all samples have enough yield.
|
|
35
|
+
|
|
36
|
+
The express QC should be checked before the standard QC.
|
|
37
|
+
"""
|
|
38
|
+
if is_case_express_priority(case):
|
|
39
|
+
return express_case_pass_sequencing_qc_on_hifi_yield(case)
|
|
40
|
+
return all(sample_has_enough_hifi_yield(sample) for sample in case.samples)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def express_case_pass_sequencing_qc_on_reads(case: Case) -> bool:
|
|
29
44
|
"""
|
|
30
45
|
Checks if all samples in an express case have enough reads.
|
|
31
46
|
"""
|
|
32
47
|
return all(express_sample_has_enough_reads(sample) for sample in case.samples)
|
|
33
48
|
|
|
34
49
|
|
|
35
|
-
def
|
|
50
|
+
def express_case_pass_sequencing_qc_on_hifi_yield(case: Case) -> bool:
|
|
51
|
+
"""
|
|
52
|
+
Checks if all samples in an express case have enough hifi yield.
|
|
53
|
+
"""
|
|
54
|
+
return all(express_sample_has_enough_yield(sample) for sample in case.samples)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def express_sample_pass_sequencing_qc_on_reads(sample: Sample) -> bool:
|
|
36
58
|
return express_sample_has_enough_reads(sample)
|
|
37
59
|
|
|
38
60
|
|
|
39
|
-
def
|
|
61
|
+
def express_sample_has_enough_reads(sample: Sample) -> bool:
|
|
62
|
+
"""
|
|
63
|
+
Checks if given express sample has enough reads. Gets the threshold from the sample's
|
|
64
|
+
application version.
|
|
65
|
+
"""
|
|
66
|
+
express_reads_threshold: int = get_express_reads_threshold_for_sample(sample)
|
|
67
|
+
enough_reads: bool = sample.reads >= express_reads_threshold
|
|
68
|
+
if not enough_reads:
|
|
69
|
+
LOG.warning(f"Sample {sample.internal_id} has too few reads.")
|
|
70
|
+
return enough_reads
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def express_sample_has_enough_yield(sample: Sample) -> bool:
|
|
74
|
+
if not sample.hifi_yield:
|
|
75
|
+
LOG.debug(f"Sample {sample.internal_id} has no hifi yield.")
|
|
76
|
+
return False
|
|
77
|
+
|
|
78
|
+
express_yield_threshold: int = get_express_yield_threshold_for_sample(sample)
|
|
79
|
+
enough_yield: bool = sample.hifi_yield >= express_yield_threshold
|
|
80
|
+
if not enough_yield:
|
|
81
|
+
LOG.warning(f"Sample {sample.internal_id} does not have enough yield.")
|
|
82
|
+
return enough_yield
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def sample_pass_sequencing_qc_on_reads(sample: Sample) -> bool:
|
|
40
86
|
"""
|
|
41
87
|
Get the standard sequencing QC of a sample. The checks are performed in the following order:
|
|
42
88
|
1. If the sample is express priority, the express QC is used.
|
|
@@ -47,7 +93,7 @@ def sample_pass_sequencing_qc(sample: Sample) -> bool:
|
|
|
47
93
|
checked before the standard QC.
|
|
48
94
|
"""
|
|
49
95
|
if is_sample_express_priority(sample):
|
|
50
|
-
return
|
|
96
|
+
return express_sample_pass_sequencing_qc_on_reads(sample)
|
|
51
97
|
if is_sample_ready_made_library(sample):
|
|
52
98
|
return ready_made_library_sample_has_enough_reads(sample)
|
|
53
99
|
return sample_has_enough_reads(sample)
|
|
@@ -87,6 +133,31 @@ def any_sample_in_case_has_reads(case: Case) -> bool:
|
|
|
87
133
|
return passed_quality_check
|
|
88
134
|
|
|
89
135
|
|
|
136
|
+
def raw_data_case_pass_qc(case: Case) -> bool:
|
|
137
|
+
if is_case_ready_made_library(case):
|
|
138
|
+
return ready_made_library_case_pass_sequencing_qc(case)
|
|
139
|
+
if is_first_sample_yield_based_and_processed(case):
|
|
140
|
+
return all(sample_has_enough_hifi_yield(sample) for sample in case.samples)
|
|
141
|
+
elif is_first_sample_reads_based_and_processed(case):
|
|
142
|
+
return all(sample_has_enough_reads(sample) for sample in case.samples)
|
|
143
|
+
LOG.warning(f"Not all samples for case {case.internal_id} have been post-processed.")
|
|
144
|
+
return False
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def is_first_sample_yield_based_and_processed(case: Case) -> bool:
|
|
148
|
+
sample: Sample = case.samples[0]
|
|
149
|
+
if metrics := sample.sample_run_metrics:
|
|
150
|
+
return metrics[0].type == DeviceType.PACBIO
|
|
151
|
+
return False
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def is_first_sample_reads_based_and_processed(case: Case) -> bool:
|
|
155
|
+
sample: Sample = case.samples[0]
|
|
156
|
+
if metrics := sample.sample_run_metrics:
|
|
157
|
+
return metrics[0].type == DeviceType.ILLUMINA
|
|
158
|
+
return False
|
|
159
|
+
|
|
160
|
+
|
|
90
161
|
def is_case_express_priority(case: Case) -> bool:
|
|
91
162
|
"""
|
|
92
163
|
Check if a case is express priority.
|
|
@@ -94,18 +165,6 @@ def is_case_express_priority(case: Case) -> bool:
|
|
|
94
165
|
return case.priority == Priority.express
|
|
95
166
|
|
|
96
167
|
|
|
97
|
-
def express_sample_has_enough_reads(sample: Sample) -> bool:
|
|
98
|
-
"""
|
|
99
|
-
Checks if given express sample has enough reads. Gets the threshold from the sample's
|
|
100
|
-
application version.
|
|
101
|
-
"""
|
|
102
|
-
express_reads_threshold: int = get_express_reads_threshold_for_sample(sample)
|
|
103
|
-
enough_reads: bool = sample.reads >= express_reads_threshold
|
|
104
|
-
if not enough_reads:
|
|
105
|
-
LOG.warning(f"Sample {sample.internal_id} has too few reads.")
|
|
106
|
-
return enough_reads
|
|
107
|
-
|
|
108
|
-
|
|
109
168
|
def get_express_reads_threshold_for_sample(sample: Sample) -> int:
|
|
110
169
|
"""
|
|
111
170
|
Get the express reads threshold for a sample.
|
|
@@ -113,6 +172,15 @@ def get_express_reads_threshold_for_sample(sample: Sample) -> int:
|
|
|
113
172
|
return round(sample.application_version.application.target_reads / 2)
|
|
114
173
|
|
|
115
174
|
|
|
175
|
+
def get_express_yield_threshold_for_sample(sample: Sample) -> int:
|
|
176
|
+
if threshold := sample.application_version.application.expected_express_hifi_yield:
|
|
177
|
+
return threshold
|
|
178
|
+
else:
|
|
179
|
+
raise ApplicationDoesNotHaveHiFiYieldError(
|
|
180
|
+
f"Application for sample {sample.internal_id} does not have target HiFi yield."
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
|
|
116
184
|
def is_sample_ready_made_library(sample: Sample) -> bool:
|
|
117
185
|
return sample.prep_category == SeqLibraryPrepCategory.READY_MADE_LIBRARY
|
|
118
186
|
|
|
@@ -143,6 +211,28 @@ def sample_has_enough_reads(sample: Sample) -> bool:
|
|
|
143
211
|
return enough_reads
|
|
144
212
|
|
|
145
213
|
|
|
214
|
+
def sample_has_enough_hifi_yield(sample: Sample) -> bool:
|
|
215
|
+
"""
|
|
216
|
+
Return true if the sample's HiFi yield is greater than or equal to the threshold.
|
|
217
|
+
Returns false if the HiFi yield is lower than the threshold or None.
|
|
218
|
+
Raises:
|
|
219
|
+
ApplicationDoesNotHaveHiFiYieldError if the sample doesn't have expected HiFi yield.
|
|
220
|
+
"""
|
|
221
|
+
if not sample.expected_hifi_yield:
|
|
222
|
+
raise ApplicationDoesNotHaveHiFiYieldError(
|
|
223
|
+
f"Application for sample {sample.internal_id} does not have target HiFi yield."
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
if not sample.hifi_yield:
|
|
227
|
+
LOG.debug(f"Sample {sample.internal_id} has no hifi yield.")
|
|
228
|
+
return False
|
|
229
|
+
|
|
230
|
+
enough_hifi_yield: bool = sample.hifi_yield >= sample.expected_hifi_yield
|
|
231
|
+
if not enough_hifi_yield:
|
|
232
|
+
LOG.warning(f"Sample {sample.internal_id} does not have enough HiFi yield.")
|
|
233
|
+
return enough_hifi_yield
|
|
234
|
+
|
|
235
|
+
|
|
146
236
|
def is_sample_express_priority(sample: Sample) -> bool:
|
|
147
237
|
"""
|
|
148
238
|
Check if a sample is express priority.
|
|
@@ -2,15 +2,13 @@ import logging
|
|
|
2
2
|
from typing import Callable
|
|
3
3
|
|
|
4
4
|
from cg.constants.constants import SequencingQCStatus
|
|
5
|
-
from cg.services.sequencing_qc_service.utils import qc_bool_to_status
|
|
6
|
-
from typing import Callable
|
|
7
|
-
|
|
8
|
-
from cg.store.models import Case, Sample
|
|
9
5
|
from cg.services.sequencing_qc_service.quality_checks.checks import (
|
|
10
|
-
run_quality_checks,
|
|
11
|
-
get_sequencing_quality_check_for_case,
|
|
12
6
|
get_sample_sequencing_quality_check,
|
|
7
|
+
get_sequencing_quality_check_for_case,
|
|
8
|
+
run_quality_checks,
|
|
13
9
|
)
|
|
10
|
+
from cg.services.sequencing_qc_service.utils import qc_bool_to_status
|
|
11
|
+
from cg.store.models import Case, Sample
|
|
14
12
|
from cg.store.store import Store
|
|
15
13
|
|
|
16
14
|
LOG = logging.getLogger(__name__)
|
|
@@ -24,10 +22,14 @@ class SequencingQCService:
|
|
|
24
22
|
"""Run QC for samples in pending or failed cases and store the aggregated score on each case."""
|
|
25
23
|
cases: list[Case] = self.store.get_cases_for_sequencing_qc()
|
|
26
24
|
for case in cases:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
LOG.debug(f"Performing sequencing QC for case: {case.internal_id}")
|
|
26
|
+
try:
|
|
27
|
+
passes_qc: bool = self.case_pass_sequencing_qc(case)
|
|
28
|
+
qc_status: SequencingQCStatus = qc_bool_to_status(passes_qc)
|
|
29
|
+
self.store.update_sequencing_qc_status(case=case, status=qc_status)
|
|
30
|
+
LOG.info(f"Sequencing QC status for case {case.internal_id}: {qc_status}")
|
|
31
|
+
except Exception as e:
|
|
32
|
+
LOG.error(f"Error found during sequencing QC of case: {case.internal_id}: {e}")
|
|
31
33
|
|
|
32
34
|
@staticmethod
|
|
33
35
|
def case_pass_sequencing_qc(case: Case) -> bool:
|
cg/store/models.py
CHANGED
|
@@ -193,9 +193,20 @@ class Application(Base):
|
|
|
193
193
|
return self.tag
|
|
194
194
|
|
|
195
195
|
@property
|
|
196
|
-
def expected_reads(self):
|
|
196
|
+
def expected_reads(self) -> float:
|
|
197
197
|
return self.target_reads * self.percent_reads_guaranteed / 100
|
|
198
198
|
|
|
199
|
+
@property
|
|
200
|
+
def expected_hifi_yield(self) -> int | None:
|
|
201
|
+
if self.target_hifi_yield and self.percent_hifi_yield_guaranteed:
|
|
202
|
+
return round(self.target_hifi_yield * self.percent_hifi_yield_guaranteed / 100)
|
|
203
|
+
else:
|
|
204
|
+
return None
|
|
205
|
+
|
|
206
|
+
@property
|
|
207
|
+
def expected_express_hifi_yield(self) -> int | None:
|
|
208
|
+
return round(self.target_hifi_yield * 0.5) if self.target_hifi_yield else None
|
|
209
|
+
|
|
199
210
|
@property
|
|
200
211
|
def analysis_type(self) -> str:
|
|
201
212
|
if self.prep_category == SeqLibraryPrepCategory.WHOLE_TRANSCRIPTOME_SEQUENCING.value:
|
|
@@ -774,10 +785,15 @@ class Sample(Base, PriorityMixin):
|
|
|
774
785
|
return self.customer.data_archive_location
|
|
775
786
|
|
|
776
787
|
@property
|
|
777
|
-
def expected_reads_for_sample(self) ->
|
|
788
|
+
def expected_reads_for_sample(self) -> float | None:
|
|
778
789
|
"""Return the expected reads of the sample."""
|
|
779
790
|
return self.application_version.application.expected_reads
|
|
780
791
|
|
|
792
|
+
@property
|
|
793
|
+
def expected_hifi_yield(self) -> int | None:
|
|
794
|
+
"""Return the expected HiFi yield of the sample."""
|
|
795
|
+
return self.application_version.application.expected_hifi_yield
|
|
796
|
+
|
|
781
797
|
@property
|
|
782
798
|
def has_reads(self) -> bool:
|
|
783
799
|
return bool(self.reads)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
cg/__init__.py,sha256=
|
|
1
|
+
cg/__init__.py,sha256=LzHKmL8dVmAmq-6AHs2IvH5WkbB5nsiiArjFCiCZoEA,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
|
|
@@ -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=
|
|
228
|
+
cg/exc.py,sha256=IYYRa6saq17OT8pA_PBdiorf2XyXTaxNV20JBkdx8QE,8418
|
|
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
|
|
@@ -853,9 +853,9 @@ cg/services/sample_run_metrics_service/dtos.py,sha256=bJ0BL-QkqXIAAIg3F9edIdzAa_
|
|
|
853
853
|
cg/services/sample_run_metrics_service/sample_run_metrics_service.py,sha256=aQvOuorTG97lUbw7OREO8nsPhO3ouQ38RwksstGwguQ,1795
|
|
854
854
|
cg/services/sample_run_metrics_service/utils.py,sha256=BwICxptnhGg8oBghCLhzHaMNu0LuEV40cSYz1e8mB0A,829
|
|
855
855
|
cg/services/sequencing_qc_service/__init__.py,sha256=OaL9dyyI6B8uRjopTIoD1zcX_H-SbGj46ZM-V-aoq6w,88
|
|
856
|
-
cg/services/sequencing_qc_service/quality_checks/checks.py,sha256=
|
|
857
|
-
cg/services/sequencing_qc_service/quality_checks/utils.py,sha256=
|
|
858
|
-
cg/services/sequencing_qc_service/sequencing_qc_service.py,sha256=
|
|
856
|
+
cg/services/sequencing_qc_service/quality_checks/checks.py,sha256=qdcHRwZD7uxrOmacyiAG4-EN6nG5z-r4rLxcReU5kSI,2593
|
|
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
|
|
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
|
|
@@ -904,7 +904,7 @@ cg/store/filters/status_panel_filters.py,sha256=qMYhIsrF9G3mjCvL9b9O2l_cmD3SfPWh
|
|
|
904
904
|
cg/store/filters/status_pool_filters.py,sha256=XcYqe2z5k_q09xpp4cleDMQ4Q3o2y7UPCkB0QUkl1ck,4308
|
|
905
905
|
cg/store/filters/status_sample_filters.py,sha256=mRpt_ik7niMjBo9K7pP8cmdfDMdr0B3I6Tt2MWXkLoc,9656
|
|
906
906
|
cg/store/filters/status_user_filters.py,sha256=sMwKeWqgEtqv8gyhbN_Uf5huPUxbOt5qEqMWVu67Zys,1328
|
|
907
|
-
cg/store/models.py,sha256=
|
|
907
|
+
cg/store/models.py,sha256=dSJRWdvqFmgIbYTlQbsZD8utH10BIjbtUKERybnlssI,43915
|
|
908
908
|
cg/store/store.py,sha256=mz1TfKPlanH2uQyhZdwe_8VKg0IdFolmromKLu668IY,630
|
|
909
909
|
cg/utils/__init__.py,sha256=gGjdV2l_hfWFCTybU6dwDk_FcItM88EIHNPaX6g1qUk,30
|
|
910
910
|
cg/utils/calculations.py,sha256=zLVJO6nNw6n7AW7fHZI56UnQ23lqJrShB4Hh2ow6-TQ,349
|
|
@@ -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.
|
|
927
|
-
cg-83.
|
|
928
|
-
cg-83.
|
|
929
|
-
cg-83.
|
|
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,,
|
|
File without changes
|