Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ClinicalSignificance support to ODM #151

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "rwslib"
version = "1.2.13"
version = "1.2.14"
description = "Rave Web Services for Python"
authors = ["Ian Sparks <[email protected]>"]
maintainers = ["Geoff Low <[email protected]>"]
Expand Down
78 changes: 77 additions & 1 deletion rwslib/builders/clinicaldata.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
)
from rwslib.builders.modm import LastUpdateMixin, MilestoneMixin
from rwslib.builders.metadata import MeasurementUnitRef
from rwslib.builders.constants import ProtocolDeviationStatus, QueryStatusType, LocationOIDType
from rwslib.builders.constants import ProtocolDeviationStatus, QueryStatusType, LocationOIDType, TransactionType
from rwslib.builders.common import Unset

from collections import OrderedDict
Expand Down Expand Up @@ -437,6 +437,8 @@ def __init__(
self.measurement_unit_ref = None
#: the list of :class:`MdsolProtocolDeviation` references on the DataPoint - *Rave Specific Attribute*
self.deviations = []
#: the clinical significance attestation for the value - *Rave Specific Attribute*
self.clinical_significance = None

def build(self, builder):
"""
Expand Down Expand Up @@ -478,6 +480,9 @@ def build(self, builder):
if self.measurement_unit_ref is not None:
self.measurement_unit_ref.build(builder)

if self.clinical_significance is not None:
self.clinical_significance.build(builder)

for query in self.queries: # type: MdsolQuery
query.build(builder)

Expand All @@ -498,6 +503,7 @@ def __lshift__(self, other):
MdsolQuery,
Annotation,
MdsolProtocolDeviation,
MdsolClinicalSignificance,
),
):
raise ValueError(
Expand All @@ -509,6 +515,7 @@ def __lshift__(self, other):
self.set_list_attribute(other, MdsolQuery, "queries")
self.set_list_attribute(other, MdsolProtocolDeviation, "deviations")
self.set_list_attribute(other, Annotation, "annotations")
self.set_single_attribute(other, MdsolClinicalSignificance, "clinical_significance")
return other


Expand Down Expand Up @@ -1442,3 +1449,72 @@ def build(self, builder):

builder.start("mdsol:Query", params)
builder.end("mdsol:Query")


class MdsolClinicalSignificance(ODMElement):
"""
Represents the mdsol:ClinicalSignificance element in ODM.
"""
def __init__(self, value: Optional[str] = None, status: Optional[str] = None, comment: Optional[str] = None, transaction_type: Optional[TransactionType] = None):
"""
Assign clinical significance data to a datapoint
:param value: Clinical significance value (should match the values set in LabAdmin)
:param status: Status of the clinical significance statement
:param comment: Comment on the Clinical Significance
:param transaction_type: TransactionType for the statement of clinical significance
"""
self.value = value
self.status = status
self.comment = comment
self.transaction_type = transaction_type

def build(self, builder):
"""
Build XML by appending to builder
"""
params = {}
if self.value:
params["Value"] = self.value
if self.status:
params["Status"] = self.status
if self.comment:
params["Comment"] = self.comment
if self.transaction_type:
params["TransactionType"] = str(self.transaction_type)
builder.start("mdsol:ClinicalSignificance", params)
builder.end("mdsol:ClinicalSignificance")


# class MdsolLabAlert(ODMElement):
# """
# Represents the mdsol:LabAlert element in ODM.
# """
# def __init__(self, type: Optional[str] = None, range: Optional[str] = None, alert: Optional[str] = None, transaction_type: Optional[TransactionType] = None):
# """
# Assign Lab Alert data to a datapoint
# :param type: Type of alert (eg High, Low)
# :param range: Range
# :param alert:
# :param transaction_type: TransactionType for the lab alert
# """
# self.type = type
# self.range = range
# self.alert = alert
# self.transaction_type = transaction_type
#
# def build(self, builder):
# """
# Build XML by appending to builder
# """
# params = {}
# if self.type:
# params["Type"] = self.type
# if self.range:
# params["Range"] = self.range
# if self.alert:
# params["Alert"] = self.alert
# if self.transaction_type:
# params["TransactionType"] = str(self.transaction_type)
# builder.start("mdsol:LabAlert", params)
# builder.end("mdsol:LabAlert")

10 changes: 10 additions & 0 deletions rwslib/builders/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,3 +340,13 @@ class LocationOIDType(enum.Enum):
SiteNumber = 'SiteNumber'
StudyEnvSiteNumber = 'StudyEnvSiteNumber'


class TransactionType(enum.Enum):
"""
Transaction Type
"""
Insert = 'Insert'
Remove = 'Remove'
Update = 'Update'
Upsert = 'Upsert'
Context = 'Context'
24 changes: 24 additions & 0 deletions tests/rwslib/builders/test_builders_clinicaldata.py
Original file line number Diff line number Diff line change
Expand Up @@ -1385,3 +1385,27 @@ def test_oid_type_study_env_site_number(self):
"01", tested.get("LocationOID")
)
self.assertEqual("001", tested.get("mdsol:StudyEnvSiteNumber"))

def test_clinical_significance(self):
obj = MdsolClinicalSignificance(value="NCS", comment="Not related")
tested = obj_to_doc(obj)
self.assertEqual("mdsol:ClinicalSignificance", tested.tag)
self.assertEqual("NCS", tested.attrib["Value"])
self.assertEqual("Not related", tested.attrib["Comment"])
idata = ItemData("ALB", "1.23")
idata << obj
tested = obj_to_doc(idata)
self.assertEqual("ItemData", tested.tag)
self.assertEqual(1, len(tested))

# def test_lab_alert(self):
# obj = MdsolLabAlert(type="High", range="15")
# tested = obj_to_doc(obj)
# self.assertEqual("mdsol:LabAlert", tested.tag)
# self.assertEqual("High", tested.attrib["Type"])
# self.assertEqual("15", tested.attrib["Range"])
# idata = ItemData("ALB", "1.23")
# idata << obj
# tested = obj_to_doc(idata)
# self.assertEqual("ItemData", tested.tag)
# self.assertEqual(1, len(tested))