Skip to content

Commit

Permalink
Merged in bugfix/RAM-4092_ptp_trs_398 (pull request #463)
Browse files Browse the repository at this point in the history
fix k_tp per TRS-398 Table 9

Approved-by: Randy Taylor
  • Loading branch information
jrkerns committed Oct 28, 2024
2 parents 0993a86 + 6be1ae9 commit a4cb23b
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 23 deletions.
11 changes: 10 additions & 1 deletion docs/source/calibration_docs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,16 @@ Equation Definitions

* Ktp (Temp/Pressure correction):

.. math:: \frac{273.2+T}{273.2+22} * \frac{101.33}{P}
.. math:: \frac{273.2+T}{273.2+20} * \frac{101.33}{P}

.. danger::

In v3.29 the equation was changed to have an air reference of 20C from 22C. Your absorbed dose values will be different by 0.7%.
This is in line with Table 9
of the TRS-398 protocol. However, there is a footnote of the table that some countries use 22C.
If you still want to use 22C as the reference temperature you can now pass a new parameter: ``ref_temp``.
The default is 20C per Table 9 but can be changed to 22C or whatever your reference temperature is.
To retain old behavior, pass ``ref_temp=22``.

.. warning:: Temperature is in Celsius and pressure is in kPa. Use the helper functions fahrenheit2celsius, mmHg2kPa, and mbar2kPa as needed.

Expand Down
20 changes: 20 additions & 0 deletions docs/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,26 @@ Legend
* :bdg-primary:`Refactor` denotes a code refactor; usually this means an efficiency boost or code cleanup.
* :bdg-danger:`Change` denotes a change that may break existing code.

v 3.29.0
--------

TRS-398
^^^^^^^

* :bdg-danger:`Change` The air reference value for ``k_tp`` has been changed to 20C from 22C. Previously,
the reference value was assumed to be the same as AAPM TG-51, but this is incorrect per Table 9.
TRS-398 ``k_tp`` values will be different: 0.7% lower. This results in an absorbed dose increase of ~0.7% at dmax. A user warning has also been added when calling
``k_tp`` describing this change.

A new parameter has been added: ``ref_temp`` with a default of 20C. If you are in a country that
uses 22C as the reference temperature you can pass ``ref_temp=22`` to the ``k_tp`` function.
Also, if you want to retain the old behavior, you can pass ``ref_temp=22``.

.. danger::

This change will affect absorbed dose TRS-398 calculations if you rely on the ``k_tp`` function. If you are using TRS-398, please verify that your
results are still accurate. We apologize for this oversight.

v 3.28.0
--------

Expand Down
49 changes: 47 additions & 2 deletions pylinac/calibration/trs398.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import warnings
import webbrowser
from abc import ABC
from datetime import datetime
Expand All @@ -10,7 +11,13 @@
from ..core.typing import NumberOrArray
from ..core.utilities import Structure, is_close
from . import tg51 as _tg51
from .tg51 import MAX_PPOL # make available to module
from .tg51 import (
MAX_PPOL,
MIN_TEMP,
MAX_TEMP,
MIN_PRESSURE,
MAX_PRESSURE,
) # make available to module
from .tg51 import (
MAX_PELEC,
MAX_PION,
Expand Down Expand Up @@ -560,12 +567,50 @@
}

# Rename common functions from TG-51
k_tp = _tg51.p_tp
k_pol = _tg51.p_pol
z_ref = _tg51.d_ref
r_50 = _tg51.r_50


def k_tp(*, temp: float, press: float, ref_temp: float = 20) -> float:
"""Calculate the temperature & pressure correction per TRS-398.
.. note::
Per Table 9 the reference air temperature is 20°C. This is difference than AAPM TG-51.
.. versionchanged:: 3.29
The reference air temperature is now 20°C from 22. The ``ref_temp`` parameter default is 20 but
can be changed via ``ref_temp``.
Parameters
----------
temp : float (17-27)
The temperature in degrees Celsius.
press : float (91-111)
The value of pressure in kPa. Can be converted from mmHg and mbar;
see :func:`~pylinac.calibration.tg51.mmHg2kPa` and :func:`~pylinac.calibration.tg51.mbar2kPa`.
ref_temp: float
The reference temperature. Default is 20°C.
"""
warnings.warn(
"In pylinac v3.29 the reference air temperature was changed from 22 to 20°C to match TRS-398 protocol. This changes k_tp values down by 0.7%.",
UserWarning,
)
argue.verify_bounds(
temp,
bounds=(MIN_TEMP, MAX_TEMP),
message="Temperature {:2.2f} out of range. Did you use Fahrenheit? Consider using the utility function fahrenheit2celsius()",
)
argue.verify_bounds(
press,
bounds=(MIN_PRESSURE, MAX_PRESSURE),
message="Pressure {:2.2f} out of range. Did you use kPa? Consider using the utility functions mmHg2kPa() or mbar2kPa()",
)
return ((273.2 + temp) / (273.2 + ref_temp)) * (101.33 / press)


def k_s(
*,
voltage_reference: int,
Expand Down
56 changes: 36 additions & 20 deletions tests_basic/test_trs398.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from unittest import TestCase

from argue import BoundsError
from parameterized import parameterized

from pylinac.calibration import trs398
from tests_basic.utils import save_file
Expand Down Expand Up @@ -58,6 +59,21 @@ def test_kq_electron(self):
trs398.kq_electron(chamber=model, r_50=r_50), kq, delta=0.001
)

@parameterized.expand(
[
(15, 101.3, 20, 0.983),
(18, 101.3, 20, 0.993),
(22, 101.3, 20, 1.007),
(26, 101.3, 20, 1.020),
(20, 110, 20, 0.921),
(22, 101.3, 22, 1.000),
]
)
def test_k_tp(self, temp, press, ref_temp, ktp):
self.assertAlmostEqual(
trs398.k_tp(temp=temp, press=press, ref_temp=ref_temp), ktp, delta=0.001
)


class TRS398Base:
temp = float
Expand Down Expand Up @@ -167,8 +183,8 @@ class MDA_TB2_2015_15x(TRS398Photon, TestCase):
m_reference = 29.28
m_opposite = -29.33
m_reduced = 29.10
dose_mu_zref = 0.779
dose_mu_zmax = 1.007
dose_mu_zref = 0.785
dose_mu_zmax = 1.014
clinical_pdd_zref = 77.4
tpr2010 = 0.762

Expand All @@ -183,8 +199,8 @@ class MDA_TB1_2015_10x(TRS398Photon, TestCase):
m_opposite = 27.784
m_reduced = 27.635
clinical_pdd_zref = 73.5
dose_mu_zref = 0.734
dose_mu_zmax = 0.998
dose_mu_zref = 0.7386
dose_mu_zmax = 1.005
tpr2010 = (73.42 / 73.7) * trs398.tpr2010_from_pdd2010(pdd2010=46.3 / 73.7)
# open_pdf = True
# print_data = True
Expand All @@ -200,16 +216,16 @@ class ACB5_2011_6x(TRS398Photon, TestCase):
m_reduced = 24.79
clinical_pdd_zref = 66.8
tissue_correction = 0.99
dose_mu_zref = 0.673
dose_mu_zmax = 1.007
dose_mu_zref = 0.677
dose_mu_zmax = 1.014

def test_zmax_adjusted(self):
self.trs398.m_reference_adjusted = 24.65
self.assertAlmostEqual(self.trs398.dose_mu_zmax_adjusted, 1.000, delta=0.0005)
self.assertAlmostEqual(self.trs398.dose_mu_zmax_adjusted, 1.007, delta=0.0005)

def test_zref_adjusted(self):
self.trs398.m_reference_adjusted = 24.65
self.assertAlmostEqual(self.trs398.dose_mu_zref_adjusted, 0.668, delta=0.0005)
self.assertAlmostEqual(self.trs398.dose_mu_zref_adjusted, 0.6725, delta=0.0005)


class ACB5_2012_6X(TRS398Photon, TestCase):
Expand All @@ -222,8 +238,8 @@ class ACB5_2012_6X(TRS398Photon, TestCase):
clinical_pdd_zref = 66.8
tpr2010 = trs398.tpr2010_from_pdd2010(pdd2010=38.4 / 66.8)
tissue_correction = 0.99
dose_mu_zref = 0.679
dose_mu_zmax = 1.0159
dose_mu_zref = 0.683
dose_mu_zmax = 1.023


class ACB5_2012_18X(TRS398Photon, TestCase):
Expand All @@ -237,8 +253,8 @@ class ACB5_2012_18X(TRS398Photon, TestCase):
m_reduced = 30.50
clinical_pdd_zref = 79.7
tissue_correction = 0.99
dose_mu_zref = 0.807
dose_mu_zmax = 1.0125
dose_mu_zref = 0.813
dose_mu_zmax = 1.0198


class IMMCTB_6FFF(TRS398Photon, TestCase):
Expand All @@ -253,8 +269,8 @@ class IMMCTB_6FFF(TRS398Photon, TestCase):
m_reduced = 11.533
clinical_pdd_zref = 63.5
mu = 100
dose_mu_zref = 0.638
dose_mu_zmax = 1.005
dose_mu_zref = 0.642
dose_mu_zmax = 1.0116
print_data = True


Expand All @@ -270,8 +286,8 @@ class IMMCTB_10FFF(TRS398Photon, TestCase):
tpr2010 = trs398.tpr2010_from_pdd2010(pdd2010=(43 / 71.2))
clinical_pdd_zref = 71.1
mu = 100
dose_mu_zref = 0.712
dose_mu_zmax = 1.0005
dose_mu_zref = 0.7165
dose_mu_zmax = 1.0077
# open_pdf = True


Expand All @@ -286,8 +302,8 @@ class IMMCTB_15X(TRS398Photon, TestCase):
clinical_pdd_zref = 76.7
tpr2010 = trs398.tpr2010_from_pdd2010(pdd2010=(49.9 / 76.9)) * (76.79 / 76.9)
mu = 100
dose_mu_zref = 0.770
dose_mu_zmax = 1.004
dose_mu_zref = 0.775
dose_mu_zmax = 1.011
# print_data = True
# open_pdf = True

Expand All @@ -305,5 +321,5 @@ class IMMC_TB_20E(TRS398Electron, TestCase):
m_reduced = 19.437 * 0.99354
i_50 = 8.22
clinical_pdd_zref = 96.8
dose_mu_zref = 0.972
dose_mu_zmax = 1.004
dose_mu_zref = 0.979
dose_mu_zmax = 1.011

0 comments on commit a4cb23b

Please sign in to comment.