Esempio n. 1
0
def p_ion(*, voltage_reference: int, voltage_reduced: int,
          m_reference: NumberOrArray, m_reduced: NumberOrArray) -> float:
    """Calculate the ion chamber collection correction.

    Parameters
    ----------
    voltage_reference : int
        The "high" voltage; same as the TG51 measurement voltage.
    voltage_reduced : int
        The "low" voltage; usually half of the high voltage.
    m_reference : float, iterable
        The readings of the ion chamber at the "high" voltage.
    m_reduced : float, iterable
        The readings of the ion chamber at the "low" voltage.

    Raises
    ------
    BoundsError if calculated Pion is outside the range 1.00-1.05.
    """
    ion = (1 - voltage_reference / voltage_reduced) / (
        np.mean(m_reference) / np.mean(m_reduced) -
        voltage_reference / voltage_reduced)
    argue.verify_bounds(
        ion,
        bounds=(1, 1.05),
        message="Pion out of range (1.00-1.05). Check inputs or chamber")
    return float(ion)
Esempio n. 2
0
def k_s(*, voltage_reference: int, voltage_reduced: int,
        m_reference: NumberOrArray, m_reduced: NumberOrArray) -> float:
    """Calculate the ion recombination effect using readings at two voltages. The voltages should have
    a ratio of 2, 2.5, 3, 3.5, 4, or 5.

    Parameters
    ----------
    voltage_reference : int
        The voltage at which calibration will be performed (e.g. 300V)
    voltage_reduced : int
        The voltage which is lower than reference (e.g. 150V)
    m_reference : array, float
        The reading(s) at the reference voltage.
    m_reduced : array, float
        The reading(s) at the reduced voltage.

    Returns
    -------
    k_s : float
        The ion recombination factor.

    Raises
    ------
    ValueError
        If the voltage ratio is not valid.
    ValueError
        If the calculated ks value is outside the range (1.0, 1.05).
    """
    v_ratio = voltage_reference / voltage_reduced
    _verify_voltage_ratio_is_valid(v_ratio)
    a = V1_V2_FITS[v_ratio]
    m_ratio = np.mean(m_reference) / np.mean(m_reduced)
    argue.verify_bounds(m_ratio, bounds=(1.0, 1.05), message="Ks is out of bounds. Verify inputs or check chamber")
    return float(a['a0'] + a['a1']*m_ratio + a['a2']*(m_ratio**2))
Esempio n. 3
0
def kp_r50(*, r_50: float) -> float:
    """Calculate k'R50 for Farmer-like chambers.

    Parameters
    ----------
    r_50 : float (2-9)
        The R50 value in cm.
    """
    argue.verify_bounds(r_50, bounds=(2, 9))
    return 0.9905 + 0.071 * np.exp(-r_50 / 3.67)
Esempio n. 4
0
def d_ref(*, i_50: float) -> float:
    """Calculate the dref of an electron beam based on the I50 depth.

    Parameters
    ----------
    i_50 : float
        The value of I50 in cm.
    """
    argue.verify_bounds(i_50,
                        bounds=argue.POSITIVE,
                        message="i50 should be positive")
    r50 = r_50(i_50=i_50)
    return 0.6 * r50 - 0.1
Esempio n. 5
0
def m_corrected(*, m_reference, k_tp, k_elec, k_pol, k_s) -> float:
    """The fully corrected chamber reading.

    Parameters
    ----------
    m_reference : array, float
        The chamber reading(s) at the calibration position.
    k_tp : float
        Temperature/Pressure correction. See :func:`~pylinac.calibration.tg51.p_tp`.
    k_elec : float
        Electrometer correction; given by the calibration laboratory.
    k_pol : float
        Polarity correction. See :func:`~pylinac.calibration.tg51.p_pol`.
    k_s : float
        Ion recombination correction. See :func:`~pylinac.calibration.trs398.k_s`.

    Returns
    -------
    m : float
        The fully corrected chamber reading.
    """
    argue.verify_bounds(k_tp, bounds=(MIN_PTP, MAX_PTP))
    argue.verify_bounds(k_elec, bounds=(MIN_PELEC, MAX_PELEC))
    argue.verify_bounds(k_pol, bounds=(MIN_PPOL, MAX_PPOL))
    argue.verify_bounds(k_s, bounds=(MIN_PION, MAX_PION))
    return float(np.mean(m_reference) * k_tp * k_elec * k_pol * k_s)
Esempio n. 6
0
def m_corrected(*, p_ion: float, p_tp: float, p_elec: float, p_pol: float,
                m_reference: NumberOrArray) -> float:
    """Calculate M_corrected, the ion chamber reading with all corrections applied.

    Parameters
    ----------
    p_ion : float (1.00-1.05)
        The ion collection correction.
    p_tp : float (0.92-1.08)
        The temperature & pressure correction.
    p_elec : float (0.98-1.02)
        The electrometer correction.
    p_pol : float (0.98-1.02)
        The polarity correction.
    m_reference : float, iterable
        The raw ion chamber reading(s).

    Returns
    -------
    float
    """
    argue.verify_bounds(p_ion, bounds=(MIN_PION, MAX_PION))
    argue.verify_bounds(p_tp, bounds=(MIN_PTP, MAX_PTP))
    argue.verify_bounds(p_elec, bounds=(MIN_PELEC, MAX_PELEC))
    argue.verify_bounds(p_pol, bounds=(MIN_PPOL, MAX_PPOL))
    return float(p_ion * p_tp * p_elec * p_pol * np.mean(m_reference))
Esempio n. 7
0
def r_50(*, i_50: float) -> float:
    """Calculate the R50 depth of an electron beam based on the I50 depth.

    Parameters
    ----------
    i_50 : float
        The value of I50 in cm.
    """
    argue.verify_bounds(i_50,
                        bounds=argue.POSITIVE,
                        message="i50 should be positive")
    if i_50 < 10:
        r50 = 1.029 * i_50 - 0.06
    else:
        r50 = 1.59 * i_50 - 0.37
    return r50
Esempio n. 8
0
def p_pol(*, m_reference: NumberOrArray, m_opposite: NumberOrArray) -> float:
    """Calculate the polarity correction.

    Parameters
    ----------
    m_reference : number, array
        The readings of the ion chamber at the reference polarity and voltage.
    m_opposite : number, array
        The readings of the ion chamber at the polarity opposite the reference. The sign does not make a difference.

    Raises
    ------
    BoundsError if calculated Ppol is >1% from 1.0.
    """
    mref_avg = np.mean(m_reference)
    mopp_avg = np.mean(m_opposite)
    polarity = (abs(mref_avg) + abs(mopp_avg))/abs(2*mref_avg)
    argue.verify_bounds(polarity, bounds=(0.99, 1.01), message="Polarity correction {:2.2f} out of range (+/-2%). Verify inputs")
    return float(polarity)
Esempio n. 9
0
def p_ion(*, voltage_reference: int, voltage_reduced: int, m_reference: NumberOrArray, m_reduced: NumberOrArray) -> float:
    """Calculate the ion chamber collection correction.

    Parameters
    ----------
    voltage_reference : int
        The "high" voltage; same as the TG51 measurement voltage.
    voltage_reduced : int
        The "low" voltage; usually half of the high voltage.
    m_reference : float, iterable
        The readings of the ion chamber at the "high" voltage.
    m_reduced : float, iterable
        The readings of the ion chamber at the "low" voltage.

    Raises
    ------
    BoundsError if calculated Pion is outside the range 1.00-1.05.
    """
    ion = (1 - voltage_reference / voltage_reduced) / (np.mean(m_reference) / np.mean(m_reduced) - voltage_reference / voltage_reduced)
    argue.verify_bounds(ion, bounds=(1, 1.05), message="Pion out of range (1.00-1.05). Check inputs or chamber")
    return float(ion)
Esempio n. 10
0
def p_pol(*, m_reference: NumberOrArray, m_opposite: NumberOrArray) -> float:
    """Calculate the polarity correction.

    Parameters
    ----------
    m_reference : number, array
        The readings of the ion chamber at the reference polarity and voltage.
    m_opposite : number, array
        The readings of the ion chamber at the polarity opposite the reference. The sign does not make a difference.

    Raises
    ------
    BoundsError if calculated Ppol is >1% from 1.0.
    """
    mref_avg = np.mean(m_reference)
    mopp_avg = np.mean(m_opposite)
    polarity = (abs(mref_avg) + abs(mopp_avg)) / abs(2 * mref_avg)
    argue.verify_bounds(
        polarity,
        bounds=(0.99, 1.01),
        message=
        "Polarity correction {:2.2f} out of range (+/-2%). Verify inputs")
    return float(polarity)
Esempio n. 11
0
def p_tp(*, temp: NumberLike, press: NumberLike) -> float:
    """Calculate the temperature & pressure correction.

    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`.
    """
    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) / 295.2) * (101.33 / press)