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
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