Commit fd8ff100 authored by Gabriel Couture's avatar Gabriel Couture

Add test for conversion, remove numpy dependency

parent 5b59ea7b
Pipeline #176 passed with stage
in 4 seconds
# coding: utf-8
# author: gabriel couture
from dvh.dvh import DVH
def is_dvh_has_a_prescription_dose(dvh: DVH) -> bool:
return False if dvh.prescription_dose is None else True
def convert_dvh_doses_to_relative(dvh: DVH) -> DVH:
if dvh.dose_unit == '%':
return dvh
if not is_dvh_has_a_prescription_dose(dvh):
raise ValueError(
'The DVH has no prescription dose. Therefor, relative doses can\'t be calculated.'
)
dvh.doses = [dose / dvh.prescription_dose for dose in dvh.doses]
dvh.dose_unit = '%'
return dvh
def convert_dvh_doses_to_absolute(dvh: DVH) -> DVH:
if dvh.dose_unit == 'GY':
return dvh
if not is_dvh_has_a_prescription_dose(dvh):
raise ValueError(
'The DVH has no prescription dose. Therefor, absolute doses can\'t be calculated from relative doses.'
)
dvh.doses = [dose * dvh.prescription_dose for dose in dvh.doses]
dvh.dose_unit = 'GY'
return dvh
# coding: utf-8
# author: gabriel couture
import numpy as np
from typing import List
class DVH:
......@@ -9,13 +9,11 @@ class DVH:
"""
VALID_DOSE_UNITS = ['GY', '%']
VALID_VOLUME_UNITS = ['CM3', '%']
VALID_DVH_TYPES = ['cumulative', 'differential']
def __init__(self, doses: np.ndarray,
volumes: np.ndarray,
def __init__(self, doses: List[float],
volumes: List[float],
dose_unit: str,
volume_unit: str,
dvh_type: str,
structure_name: str = None,
prescription_dose: float = None):
self.doses = doses
......@@ -24,12 +22,10 @@ class DVH:
self.dose_unit = dose_unit
self.volume_unit = volume_unit
self.type = dvh_type
self.prescription_dose = prescription_dose
self.structure_name = structure_name
self._valid_units_format()
self._valid_dvh_type()
def _valid_units_format(self) -> None:
if not self._does_dose_unit_has_valid_format():
......@@ -47,10 +43,3 @@ class DVH:
def _does_volume_unit_has_valid_format(self) -> bool:
return True if self.volume_unit in DVH.VALID_VOLUME_UNITS else False
def _valid_dvh_type(self):
if self.type not in DVH.VALID_DVH_TYPES:
raise ValueError(
f'dvh_type should be in {DVH.VALID_DVH_TYPES}, given dvh_type is {self.type}'
)
# coding: utf-8
# author: gabriel couture
import unittest
from unittest.mock import Mock
from dvh import conversion
from dvh.dvh import DVH
class TestConversion(unittest.TestCase):
ABSOLUTE_DOSE_UNIT = 'GY'
RELATIVE_DOSE_UNIT = '%'
A_PRESCRIPTION_DOSE = 15
A_DOSE_ARRAY = list(range(0, 16))
def test_givenADVHWithAbsoluteDosesAndPrescriptionDose_whenConvertingDVHDoseToRelative_thenResultIsADVHWithRelativeDoses(self):
a_dvh_with_absolute_doses = self._setup_dvh_with_absolute_doses()
a_dvh_with_absolute_doses.prescription_dose = TestConversion.A_PRESCRIPTION_DOSE
result = conversion.convert_dvh_doses_to_relative(a_dvh_with_absolute_doses)
expected_dose_array = [dose / TestConversion.A_PRESCRIPTION_DOSE for dose in TestConversion.A_DOSE_ARRAY]
self.assertEqual(result.dose_unit, TestConversion.RELATIVE_DOSE_UNIT)
self.assertEqual(result.doses, expected_dose_array)
def _setup_dvh_with_absolute_doses(self) -> DVH:
dvh = Mock()
dvh.doses = TestConversion.A_DOSE_ARRAY
dvh.dose_unit = TestConversion.ABSOLUTE_DOSE_UNIT
return dvh
......@@ -2,8 +2,6 @@
# author: gabriel couture
import unittest
import numpy as np
from dvh.dvh import DVH
......@@ -14,23 +12,8 @@ class TestDVH(unittest.TestCase):
A_VALID_VOLUME_UNIT = 'CM3'
AN_INVALID_VOLUME_UNIT = 'cc'
A_VALID_DVH_TYPE = 'cumulative'
AN_INVALID_DVH_TYPE = 'an_invalid_dvh_type'
A_DOSE_ARRAY = np.linspace(1, 2, 100)
A_VOLUME_ARRAY = np.linspace(2, 1, 100)
def setUp(self) -> None:
self.a_dvh = DVH(
doses=TestDVH.A_DOSE_ARRAY,
volumes=TestDVH.A_VOLUME_ARRAY,
dose_unit=TestDVH.A_VALID_DOSE_UNIT,
volume_unit=TestDVH.A_VALID_VOLUME_UNIT,
dvh_type=TestDVH.A_VALID_DVH_TYPE,
)
def tearDown(self) -> None:
self.a_dvh = None
A_DOSE_ARRAY = list(range(16))
A_VOLUME_ARRAY = list(range(16))[::-1]
def test_givenValidDataAndUnitsAndDVHType_whenCreatingADVH_thenResultIsADVH(self):
result = DVH(
......@@ -38,7 +21,6 @@ class TestDVH(unittest.TestCase):
volumes=TestDVH.A_VOLUME_ARRAY,
dose_unit=TestDVH.A_VALID_DOSE_UNIT,
volume_unit=TestDVH.A_VALID_VOLUME_UNIT,
dvh_type=TestDVH.A_VALID_DVH_TYPE,
)
self.assertIsInstance(result, DVH)
......@@ -51,7 +33,6 @@ class TestDVH(unittest.TestCase):
volumes=TestDVH.A_VOLUME_ARRAY,
dose_unit=TestDVH.AN_INVALID_DOSE_UNIT,
volume_unit=TestDVH.A_VALID_VOLUME_UNIT,
dvh_type=TestDVH.A_VALID_DVH_TYPE,
)
)
......@@ -63,19 +44,5 @@ class TestDVH(unittest.TestCase):
volumes=TestDVH.A_VOLUME_ARRAY,
dose_unit=TestDVH.A_VALID_DOSE_UNIT,
volume_unit=TestDVH.AN_INVALID_VOLUME_UNIT,
dvh_type=TestDVH.A_VALID_DVH_TYPE,
)
)
def test_givenAnInvalidDVHType_whenCreatingADVH_thenRaiseValueError(self):
self.assertRaises(
ValueError,
lambda: DVH(
doses=TestDVH.A_DOSE_ARRAY,
volumes=TestDVH.A_VOLUME_ARRAY,
dose_unit=TestDVH.A_VALID_DOSE_UNIT,
volume_unit=TestDVH.A_VALID_VOLUME_UNIT,
dvh_type=TestDVH.AN_INVALID_DVH_TYPE,
)
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment