Skip to content

Commit

Permalink
Patch TWIST EPPs to take new UDF "Maximum input amount (ng)" into con…
Browse files Browse the repository at this point in the history
…sideration (#457)(patch)

### Added
- new functions to fetch the maximum input amount of samples

### Changed
- the threshold used when assessing input amounts
  • Loading branch information
Karl-Svard authored Dec 4, 2023
1 parent ef435af commit 0040273
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 17 deletions.
14 changes: 8 additions & 6 deletions cg_lims/EPPs/udf/calculate/twist_aliquot_amount.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from cg_lims.exceptions import LimsError, MissingUDFsError
from cg_lims.get.artifacts import get_artifacts
from cg_lims.get.udfs import get_maximum_amount

LOG = logging.getLogger(__name__)

Expand All @@ -21,16 +22,17 @@ def set_amount_needed(artifacts: List[Artifact]):
Any amount below this can be used in the prep if the total amount is limited."""

missing_udfs = 0
for art in artifacts:
amount = art.udf.get("Amount (ng)")
for artifact in artifacts:
amount = artifact.udf.get("Amount (ng)")
maximum_amount = get_maximum_amount(artifact=artifact, default_amount=MAXIMUM_SAMPLE_AMOUNT)
if not amount:
missing_udfs += 1
continue
if amount >= MAXIMUM_SAMPLE_AMOUNT:
art.udf["Amount needed (ng)"] = MAXIMUM_SAMPLE_AMOUNT
if amount >= maximum_amount:
artifact.udf["Amount needed (ng)"] = maximum_amount
else:
art.udf["Amount needed (ng)"] = amount
art.put()
artifact.udf["Amount needed (ng)"] = amount
artifact.put()

if missing_udfs:
raise MissingUDFsError(f"Udf missing for {missing_udfs} samples")
Expand Down
21 changes: 11 additions & 10 deletions cg_lims/EPPs/udf/calculate/twist_qc_amount.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,25 @@
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
from cg_lims.get.udfs import get_maximum_amount

LOG = logging.getLogger(__name__)

MAXIMUM_SAMPLE_AMOUNT = 250

def get_qc(source: str, conc: float, amount: float) -> str:

def get_qc(source: str, conc: float, amount: float, max_amount: float) -> str:
"""QC-criteria depends on sample source, total amount and sample concentration. See AMS doc 1117, 1993 and 2125.
The volume is subtracted by 3 in the calculations. This is beacause the lab uses 3 ul in the initial qc measurements.
The volume is subtracted by 3 in the calculations. This is because the lab uses 3 ul in the initial qc measurements.
"""

qc = "FAILED"

if source == "cell-free DNA" or source == "cfDNA":
if amount >= 10 and conc <= 250 and conc >= 0.2:
if amount >= 10 and 250 >= conc >= 0.2:
qc = "PASSED"
else:
if amount >= 250 and conc <= 250 and conc >= 8.33:
if amount >= max_amount and 250 >= conc >= 8.33:
qc = "PASSED"

return qc


Expand All @@ -35,7 +36,7 @@ def calculate_amount_and_set_qc(artifacts: List[Artifact]) -> None:
missing_udfs_count = 0
qc_fail_count = 0
for artifact in artifacts:
sample = get_one_sample_from_artifact(artifact)
sample = get_one_sample_from_artifact(artifact=artifact)
source = sample.udf.get("Source")
vol = artifact.udf.get("Volume (ul)")
conc = artifact.udf.get("Concentration")
Expand All @@ -45,7 +46,8 @@ def calculate_amount_and_set_qc(artifacts: List[Artifact]) -> None:

amount = conc * (vol - 3)
artifact.udf["Amount (ng)"] = amount
qc = get_qc(source, conc, 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)
if qc == "FAILED":
qc_fail_count += 1
LOG.info(
Expand All @@ -70,11 +72,10 @@ def twist_qc_amount(ctx):
LOG.info(f"Running {ctx.command_path} with params: {ctx.params}")

process = ctx.obj["process"]
lims = ctx.obj["lims"]

try:
artifacts = get_artifacts(process=process, measurement=True)
calculate_amount_and_set_qc(artifacts)
calculate_amount_and_set_qc(artifacts=artifacts)
message = "Amounts have been calculated and qc flags set for all samples."
LOG.info(message)
click.echo(message)
Expand Down
11 changes: 10 additions & 1 deletion cg_lims/get/udfs.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from datetime import date
from enum import Enum
from typing import Optional
from genologics.entities import Entity
from genologics.entities import Entity, Artifact
from genologics.lims import Lims

from cg_lims.exceptions import MissingUDFsError
Expand Down Expand Up @@ -50,3 +50,12 @@ def get_q30_threshold(entity: Entity) -> Optional[str]:
return get_udf(entity, UserDefinedFields.Q30_THRESHOLD.value)
except MissingUDFsError:
return None


def get_maximum_amount(artifact: Artifact, default_amount: float) -> float:
"""Return the maximum allowed input amount of an artifact. A default value is returned if no UDF has been set."""
sample = artifact.samples[0]
maximum_amount = sample.udf.get("Maximum input amount (ng)")
if maximum_amount:
return maximum_amount
return default_amount

0 comments on commit 0040273

Please sign in to comment.