diff --git a/cg_lims/EPPs/udf/calculate/calculate_amount_ng.py b/cg_lims/EPPs/udf/calculate/calculate_amount_ng.py index bde917e0..3b50513e 100644 --- a/cg_lims/EPPs/udf/calculate/calculate_amount_ng.py +++ b/cg_lims/EPPs/udf/calculate/calculate_amount_ng.py @@ -15,7 +15,8 @@ @options.concentration_udf() @options.amount_udf_option() @options.volume_udf() -@options.subtract_volume_option() +@options.subtract_volume() +@options.preset_volume() @options.measurement() @options.input() @click.pass_context @@ -25,12 +26,14 @@ def calculate_amount_ng( volume_udf: str, concentration_udf: str, subtract_volume: str, + preset_volume: float, measurement: bool = False, input: bool = False, ): """Calculates and auto-fills the quantities of DNA in sample from concentration and volume - measurements. The volume is subtracted by either 0 or 3 in the calculations. This is - because the lab uses 0 or 3 ul in the initial qc measurements.""" + measurements. The volume can be subtracted by an optional specification in the cli. This is + because the lab uses some microliters of the sample in the qc measurements. A pre-set + volume can be set in the cli as well.""" LOG.info(f"Running {ctx.command_path} with params: {ctx.params}") @@ -43,13 +46,15 @@ def calculate_amount_ng( missing_udfs_count: int = 0 artifacts_with_missing_udf: List = [] for artifact in artifacts: - vol: float = artifact.udf.get(volume_udf) + if preset_volume: + vol = float(preset_volume) + elif volume_udf: + vol = artifact.udf.get(volume_udf) conc: float = artifact.udf.get(concentration_udf) if None in [conc, vol]: missing_udfs_count += 1 artifacts_with_missing_udf.append(artifact.id) continue - artifact.udf[amount_udf] = conc * (vol - int(subtract_volume)) artifact.put() if missing_udfs_count: diff --git a/cg_lims/EPPs/udf/calculate/twist_qc_amount.py b/cg_lims/EPPs/udf/calculate/twist_qc_amount.py index f3a35b29..f0057326 100644 --- a/cg_lims/EPPs/udf/calculate/twist_qc_amount.py +++ b/cg_lims/EPPs/udf/calculate/twist_qc_amount.py @@ -3,6 +3,7 @@ from typing import List import click +from cg_lims import options from cg_lims.exceptions import FailingQCError, LimsError, MissingUDFsError from cg_lims.get.artifacts import get_artifacts from cg_lims.get.samples import get_one_sample_from_artifact @@ -29,7 +30,7 @@ def get_qc(source: str, conc: float, amount: float, max_amount: float) -> str: return qc -def calculate_amount_and_set_qc(artifacts: List[Artifact]) -> None: +def calculate_amount_and_set_qc(artifacts: List[Artifact], subtract_volume: int) -> None: """Calculate amount and set qc for twist samples""" missing_udfs_count = 0 @@ -43,7 +44,7 @@ def calculate_amount_and_set_qc(artifacts: List[Artifact]) -> None: missing_udfs_count += 1 continue - amount = conc * (vol - 3) + amount = conc * (vol - subtract_volume) artifact.udf["Amount (ng)"] = amount max_amount = get_maximum_amount(artifact=artifact, default_amount=MAXIMUM_SAMPLE_AMOUNT) qc = get_qc(source=source, conc=conc, amount=amount, max_amount=max_amount) @@ -64,8 +65,12 @@ def calculate_amount_and_set_qc(artifacts: List[Artifact]) -> None: @click.command() +@options.subtract_volume() @click.pass_context -def twist_qc_amount(ctx): +def twist_qc_amount( + ctx: click.Context, + subtract_volume: str, +): """Calculates amount of samples for qc validation.""" LOG.info(f"Running {ctx.command_path} with params: {ctx.params}") @@ -74,7 +79,7 @@ def twist_qc_amount(ctx): try: artifacts = get_artifacts(process=process, measurement=True) - calculate_amount_and_set_qc(artifacts=artifacts) + calculate_amount_and_set_qc(artifacts=artifacts, subtract_volume=int(subtract_volume)) message = "Amounts have been calculated and qc flags set for all samples." LOG.info(message) click.echo(message) diff --git a/tests/EPPs/udf/calculate/test_twist_qc_amount.py b/tests/EPPs/udf/calculate/test_twist_qc_amount.py index ef601dc7..8976b545 100644 --- a/tests/EPPs/udf/calculate/test_twist_qc_amount.py +++ b/tests/EPPs/udf/calculate/test_twist_qc_amount.py @@ -7,14 +7,15 @@ @pytest.mark.parametrize( - "volume,concentration,source", - [(3, 1, "blood"), (10, 0.1, "cfDNA"), (50, 300, "blood"), (300, 2, "blood"), (10, 10, "blood")], + "volume,concentration,source,subtract", + [(3, 1, "blood",2), (10, 0.1, "cfDNA",2), (50, 300, "blood",2), (300, 2, "blood",2), (10, 10, "blood",2)], ) def test_calculate_amount_and_set_qc_failing( - volume: int, concentration: float, source: int, artifact_1: Artifact, sample_1: Sample + volume: int, concentration: float, source: int, artifact_1: Artifact, sample_1: Sample, subtract: int ): # GIVEN: A sample with udf Source: , # and a related Artifact with udfs: Concentration: and Volume (ul): + # and a subtraction volume server("flat_tests") artifact_1.udf["Volume (ul)"] = volume artifact_1.udf["Concentration"] = concentration @@ -26,13 +27,13 @@ def test_calculate_amount_and_set_qc_failing( # THEN FailingQCError is being raised and the artifacts should be FAILED with pytest.raises(FailingQCError): - calculate_amount_and_set_qc(artifacts=[artifact_1]) + calculate_amount_and_set_qc(artifacts=[artifact_1], subtract_volume=subtract) assert artifact_1.qc_flag == "FAILED" -@pytest.mark.parametrize("volume,concentration,source", [(35, 10, "cfDNA"), (50, 50, "blood")]) +@pytest.mark.parametrize("volume,concentration,source,subtract", [(35, 10, "cfDNA",2), (50, 50, "blood",2)]) def test_calculate_amount_and_set_qc_passing( - volume: int, concentration: float, source: int, artifact_1: Artifact, sample_1: Sample + volume: int, concentration: float, source: int, artifact_1: Artifact, sample_1: Sample, subtract: int ): # GIVEN: A sample with udf Source: , # and a related Artifact with udfs: Concentration: and Volume (ul): @@ -46,7 +47,7 @@ def test_calculate_amount_and_set_qc_passing( sample_1.put() # WHEN running calculate_amount_and_set_qc - calculate_amount_and_set_qc(artifacts=[artifact_1]) + calculate_amount_and_set_qc(artifacts=[artifact_1], subtract_volume=subtract) # THEN the artifacts should be PASSED assert artifact_1.qc_flag == "PASSED" @@ -67,4 +68,4 @@ def test_calculate_amount_and_set_qc_missing_udf( # WHEN running calculate_amount_and_set_qc # THEN MissingUDFsError is being raised with pytest.raises(MissingUDFsError): - calculate_amount_and_set_qc(artifacts=artifacts) + calculate_amount_and_set_qc(artifacts=artifacts, subtract_volume=2)