Source code for pytrip.models.tcp

#
#    Copyright (C) 2010-2017 PyTRiP98 Developers.
#
#    This file is part of PyTRiP98.
#
#    PyTRiP98 is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    PyTRiP98 is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with PyTRiP98.  If not, see <http://www.gnu.org/licenses/>.
#
"""
TCP models
"""

import numpy as np
import logging

logger = logging.getLogger(__name__)


[docs]def tcp_voi(sf, voi=None, ncells=1.0, fractions=1): """ Returns TCP within VOI. If VOI is not give, TCP of entire cube is calculated. This is equation (7) in https://doi.org/10.1093/jrr/rru020 assuming static oxygenation during all fractions. (Equation (8) would require a new oxy cube after every fractionation, not implemented.) :params numpy.array sf: numpy array, surviving fraction cube :params Voi voi: pytrip Voi() class object :params float ncells: number of cells in each voxel, or a cube of surviving fractions :params int fractions: number of fractions, default is 1 """ tcp = 0 if voi is None: mask = None else: # mark ony those values as true, which are within the VOI voi_cube = voi.get_voi_cube() mask = (voi_cube.cube == 1000) # ncells may be either a scalar or a cube. if np.isscalar(ncells): tcp = np.exp(-sum(ncells * sf[mask]**fractions)) else: # better make sure that the cells cube has the same size as the surviving fraction cube if ncells.shape == sf.shape: tcp = np.exp(-sum(ncells[mask] * sf[mask]**fractions)) else: logger.error("ncells array shape does not match surviving fraction shape.") return tcp