Ejemplo n.º 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)
Ejemplo n.º 2
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)
Ejemplo n.º 3
0
    def index_to_coordinate(self, index: Union[Tuple, np.ndarray],
                            scaling: Coordinate) -> Coordinate:
        """
        Converts an index to the model_type to a coordinate in mm.

        :param index: index into the VoxelModelData.data np.array
        :param scaling: scaling of the parent voxel model.
        :return:
        """
        # make sure that the index is 1-dimensional if it is an numpy array
        if type(index) is np.ndarray:
            # make a copy such that the original index is not altered
            index = np.copy(index)
            index.shape = (-1, )

        # add any possible offset from the model_type
        index += np.array(
            [self.mask['x'].start, self.mask['y'].start, self.mask['z'].start])

        return Coordinate(index * scaling)
Ejemplo n.º 4
0
# Calculate the trunk model
start_slice = int(96)
end_slice = int(141)

(model_trunk, trunk_mask) = AVW_Data.calculate_trunk_model(Donna,
                                                           'complete',
                                                           z_start=start_slice,
                                                           z_end=end_slice)
outer_shape_trunk = AVW_Data.calculate_outer_shape(model_trunk)

Donna.add_voxel_data(
    short_name='trunk',
    name="The trunk of the 'complete' model. Arms have been removed using "
    "VoxelModel.remove_arms().",
    outer_shape=outer_shape_trunk,
    model=model_trunk,
    mask=trunk_mask,
    tissue_mapping=None)

# Calculate the 3D surface of Donna
surface = Donna.create_3d_model(model_type='trunk', patch_size=(30, 30))
Donna.models['trunk'].surface_3d = surface

Donna.models['trunk'].endpoints = []
for (i, s) in enumerate(surface):
    Donna.models['trunk'].endpoints.append(Coordinate(np.array(
        s['centroid'])))  #

Donna.save_model()
Ejemplo n.º 5
0
# is continuous and the arms are removed in all z-layers
model_trunk[61, 97:99, 253] = np.array([42, 42])
model_trunk = AustinWoman.remove_arms(model_trunk)
trunk_mask = {
    'x': range(0, model_trunk.shape[0]),
    'y': range(0, model_trunk.shape[1]),
    'z': range(z_start, z_end)
}

outer_shape_trunk = txt_data.calculate_outer_shape(model_trunk)

AustinWoman.add_voxel_data(
    short_name='trunk',
    name="The trunk of the 'complete' model. Arms have been removed using "
    "VoxelModel.remove_arms().",
    outer_shape=outer_shape_trunk,
    model=model_trunk,
    mask=trunk_mask,
    tissue_mapping=None)

surface = AustinWoman.create_3d_model(model_type='trunk', patch_size=(30, 30))
AustinWoman.models['trunk'].surface_3d = surface
surface = AustinWoman.models['trunk'].surface_3d
AustinWoman.models['trunk'].endpoints = []
for (i, s) in enumerate(surface):
    AustinWoman.models['trunk'].endpoints.append(
        Coordinate(np.array(s['centroid'])))

# save the model
AustinWoman.save_model()
Ejemplo n.º 6
0
                            tissue_names=tissue_name_orig)

VisibleHuman.add_voxel_data(short_name='complete',
                            name='The \'original\' model converted to our TissueProperties.',
                            model=VisibleHuman.models['original'].data,
                            outer_shape=outer_shape,
                            tissue_mapping=tissue_mapping)

# calculate the trunk model
# the slice z_end will not be included in the final model
(model_trunk, trunk_mask) = AVW_Data.calculate_trunk_model(VisibleHuman, model_type='complete', z_start=75, z_end=196)
outer_shape_trunk = AVW_Data.calculate_outer_shape(model_trunk)

VisibleHuman.add_voxel_data(short_name='trunk',
                            name="The trunk of the 'complete' model. Arms have been removed using "
                                 "VoxelModel.remove_arms().",
                            outer_shape=outer_shape_trunk,
                            model=model_trunk,
                            mask=trunk_mask,
                            tissue_mapping=None)

surface = VisibleHuman.create_3d_model(model_type='trunk', patch_size=(30, 30))
VisibleHuman.models['trunk'].surface_3d = surface

VisibleHuman.models['trunk'].endpoints = []
for (i, s) in enumerate(surface):
    VisibleHuman.models['trunk'].endpoints.append(Coordinate(np.array(s['centroid'])))


VisibleHuman.save_model()