Exemple #1
0
    def get_tissues_from_voxel_model(self, voxel_model: VoxelModel=VoxelModel(),
                                     startpoint: Coordinate=Coordinate([0, 0, 0]),
                                     endpoint: Coordinate=Coordinate([1, 1, 1]),
                                     model_type: str='trunk'):
        """
        Determine the tissues between start and endpoint in self.voxel_model
        :param voxel_model: The VoxelModel to investigate
        :param startpoint: the startpoint
        :param endpoint: the endpoint
        :param model_type: the type of the model to use, e.g. 'complete' or 'trunk'
        :return:
        """
        # Find the tissues between startpoint_mm and endpoint_mm
        tissues = voxel_model.tissue_finding_3D(startpoint, endpoint, model_type=model_type)
        self.tissue_array = tissues['tissue_array']
        self.depth_array = tissues['depth_array']
        self.endpoint = tissues['endpoint']
        self.source_tissue = tissues['source_tissue']

        # Find the tissues needed for the source impedance calculation
        # For calculation of the source impedance we need the tissue layers in the opposite direction for about 100 mm.
        # Due to the heavy attenuation this should be sufficient.
        # As the direction of the line in tissue_finding is calculated based on the voxel indices do the same here:
        startpoint_d = np.around(startpoint / voxel_model.scaling).astype(int)
        endpoint_d = np.around(endpoint / voxel_model.scaling).astype(int)
        # direction in voxel indices:
        direction_d = (endpoint_d - startpoint_d)
        # direction in coordinates
        direction = direction_d * voxel_model.scaling / np.linalg.norm(direction_d * voxel_model.scaling)

        # it can happen that the voxel 100mm in the opposite direction is outside the model.
        # for that reason check if it is inside (by a test conversion to index) and otherwise reduce the distance
        distance = 100  # mm
        while distance >= 0:
            # calculate the endpoint for the source impedance calculation
            source_endpoint = startpoint - distance * direction  # 100 mm in opposite direction
            try:
                voxel_model.models[model_type].coordinate_to_index(source_endpoint, voxel_model.scaling)
                break
            except IndexError:
                distance -= 5
                logging.debug("source_endpoint = %s is outside model! "
                              "Distance reduced from 100 mm to %d (startpoint = %s, endpoint = %s) "
                              % (str(source_endpoint),  distance, str(startpoint), str(endpoint)))

        if distance < 100:
            logging.warning("Distance for source impedance calculation was reduced fromm 100 mm to %d mm" % distance)

        tissues = voxel_model.tissue_finding_3D(startpoint, source_endpoint,
                                                return_load_tissue=True, model_type=model_type)
        self.source_impedance_tissue_array = tissues['tissue_array']
        self.source_impedance_depth_array = tissues['depth_array']
        self.source_impedance_load_tissue = tissues['load_tissue']

        # Calculate the distance between transmitter and receiver
        self.distance = np.sum(self.depth_array)
    def calculate_trunk_model(voxel_model: VoxelModel, model_type: str, z_start: int, z_end: int)\
            -> Tuple[np.ndarray, Dict]:
        """
        Calculate the trunk model
        the slice z_end will not be included in the final model
        :param voxel_model:      the voxel model that is converted to a trunk only model
        :param model_type:      the model_type that is used as basis for the conversion
        :param z_start:         start slice
        :param z_end:           end slice (not included)

        """

        logging.info("Calculate the trunk model..")
        model_trunk = voxel_model.models[model_type][:, :, z_start:z_end]
        model_trunk = voxel_model.remove_arms(model_trunk)

        mask_trunk = {'x': range(0, model_trunk.shape[0]),
                      'y': range(0, model_trunk.shape[1]),
                      'z': range(z_start, z_end)}

        return model_trunk, mask_trunk
Exemple #3
0
    def __init__(self, voxel_model: VoxelModel=VoxelModel(),
                 startpoint: Coordinate=Coordinate([0, 0, 0]), endpoint: Coordinate=Coordinate([1, 1, 1]),
                 tissue_properties: DielectricProperties=TissueProperties(),
                 model_type: str = 'trunk'):
        """
        Generate the layer model for voxel_model

        :param TissueProperties tissue_properties:  Object containing the dielectric tissue properties
        :param VoxelModel voxel_model:              A VoxelModel object that is used for the calculation of the layers
        :param numpy.ndarray startpoint:            Startpoint coordinate (transmitter location) inside the VoxelModel
        :param numpy.ndarray endpoint:              Endpoint coordinate (receiver location) outside the VoxelModel
        :param model_type:   the type of the model to use, e.g. 'complete' or 'trunk'
        """
        # The tissue property object is used to calculate the dielectric properties
        self.tissue_properties = tissue_properties  # TissueProperties()
        # fix the startpoint
        self.startpoint = startpoint

        self.tissue_array = np.zeros(shape=(0,))
        self.depth_array = np.zeros(shape=(0,))
        self.endpoint = endpoint

        self.source_tissue = 0
        # if an empy layer model is created, assume a layer of 1000mm air as source medium
        self.source_impedance_tissue_array = np.array([0])
        self.source_impedance_depth_array = np.array([[1000]]) * 1e-3
        self.source_impedance_load_tissue = np.array([0])
        # the distance between transmitter and receiver
        self.distance = 0

        self.vm = voxel_model
        # check if the voxel_model is empty
        # only get the tissue layers from the model if it is not empty
        # otherwise the tissue layers need be set individually by hand
        if voxel_model.name is not 'empty':
            self.get_tissues_from_voxel_model(voxel_model, startpoint, endpoint, model_type=model_type)
current_directory = os.path.dirname(__file__)
base_path = os.path.join(current_directory, '..', '..', '..',
                         'Numerical Human Phantoms', 'Donna')

# path to the AVW File of this model
filename = os.path.join(base_path, 'segm_donna')
# path to the tissue_mapping file
tissue_file = os.path.join('ImportDonna_tissues.txt')

AVW_Data = VoxelModelImporter(filename, tissue_file, 'AVW')
model_orig = AVW_Data.data['image']
tissue_name_orig = AVW_Data.tissue_names
tissue_mapping = AVW_Data.tissue_mapping

Donna = VoxelModel()
Donna.show_progress_bar = True

# needs to be set manually from README.txt
Donna.set_scale(1.875, 1.875, 10)

Donna.name = 'Donna'
Donna.description = 'Donna model from the Helmholtz Zentrum München. ' \
                    'Resolution %.2fmm x %.2fmm x %.2fmm' % (Donna.scaling.x,
                                                             Donna.scaling.y, Donna.scaling.z)

#  Calculate the outer_shape of the original and the complete model
outer_shape = AVW_Data.calculate_outer_shape(model_orig, tissue_mapping)

Donna.add_voxel_data(short_name='original',
                     name='Original data from AVW file',
from LayerModel_lib.voxelmodel import VoxelModel
from LayerModel_lib.voxelmodel_importer import VoxelModelImporter
from LayerModel_lib.coordinate import Coordinate

current_directory = os.path.dirname(__file__)
base_path = os.path.join(current_directory, '..', 'Numerical Human Phantoms unzipped')

# Folder with all the txt-files of the AustinMan model
txt_files_dir = os.path.join(base_path, 'AustinMan-v2_5-2x2x2 txt')

# file with all the tissue ids and the mapping between our TissueProperties and the one in the model
tissue_mapping_file = os.path.join('ImportAustinXXX_TissuesMaterialv2_3.txt')

# Define VoxelModel Object to store all properties of the AustinMan VoxelModel
AustinMan = VoxelModel()
AustinMan.show_progress_bar = True
# Set the name
AustinMan.name = 'AustinMan_v2.5_2x2x2'
AustinMan.description = 'AustinMan v2.5, Resolution: 2mm x 2mm x 2mm'

# get all the data from the txt files
txt_data = VoxelModelImporter(txt_files_dir, tissue_mapping_file, 'TXT', show_progress=True)

# the scale of the model in millimeter
scale = txt_data.data['scale']
AustinMan.set_scale(scale['x'], scale['y'], scale['z'])
# the original voxel model
model_orig = txt_data.data['image']
# the tissue names
tissue_name_orig = txt_data.tissue_names