Working with a realistic 3d model

This example demonstrates how the functions introduced in the previous examples can be used to simulate light propagation in a mouse. Please note that the model is not part of this work and is not distributed here. The digimouse model can be obtained from http://neuroimage.usc.edu/mouse_atlas/tesselated_atlas.zip For information how to cite the mouse see http://neuroimage.usc.edu/neuro/Digimouse

Contents

if(exist('Tesselated_Atlas.mat', 'file') ~= 2)
    error('Could not find the mesh data file. Please unzip Tesselated_Atlas.mat from http://neuroimage.usc.edu/mouse_atlas/tesselated_atlas.zip to the examples folder.');
end

load 'Tesselated_Atlas.mat'

Build mesh

The model is not exactly in the format needed. The surface is given as a separate array, therefore the surface triangles are mapped to the volumetric mesh

surface_coordinates = find(ismember(r,r_hull,'rows'));  % find the surface coordinates from the volumetric mesh
vmcmesh.BH = surface_coordinates(S_hull); % map the surface triangles to mesh triangles
% The rest of the mesh definition is in the right format
vmcmesh.r = r;
vmcmesh.H = T;

Display the surface mesh

figure('rend','painters','pos',[10 10 1200 700])
hold on
trimesh(vmcmesh.BH,vmcmesh.r(:,1),vmcmesh.r(:,2),vmcmesh.r(:,3),'facecolor', 'r','FaceAlpha',0.2);
view(70,40);
% Display the heart of the mouse (see labels_4_tetrahedrons.txt)
tetramesh(vmcmesh.H(cond==3,:), vmcmesh.r);
hold off

Create a medium and a boundary for the mesh

vmcmedium.absorption_coefficient=0.03;
vmcmedium.scattering_coefficient=0.3;
vmcmedium.scattering_anisotropy=0.9;
vmcmedium.refractive_index=1.3;

vmcmedium=createMedium(vmcmesh,vmcmedium);
vmcboundary=createBoundary(vmcmesh,vmcmedium);

% Find the approximate center of the heart by taking the mean of the
% of the tetrahedrons that it consist of
heart_location = mean(vmcmesh.r(vmcmesh.H(cond==3,1),:));
% For illustration purposes, we set the absorbtion coefficient of the heart
% 3 times bigger as the rest of the body
vmcmedium.absorption_coefficient(cond==3)=0.09;

% To attach a light source, find boundary elements above it
surface_above_heart = findBoundaries(vmcmesh, 'direction', ...
heart_location, ... % obtain the surface elements from a region that starts
heart_location+[0 0 20], ... %  at the heart location and ends above it
5); % radius of the region

vmcboundary.lightsource(surface_above_heart) = {'cosinic'};

Run the simulation

solution = ValoMC(vmcmesh, vmcmedium, vmcboundary);
                 ValoMC-3D
--------------------------------------------
  Version:  v1.0b-118-g853f111
  Revision: 131
  OpenMP enabled                     
  Using 16 threads
--------------------------------------------
Initializing MC3D...
Computing... 
...done

Done

Fill the mesh region with a grid for plotting

Create a grid and obtain values from the mesh to the grid

mincoord = min(vmcmesh.r);
maxcoord = max(vmcmesh.r);

[gridx,gridy,gridz] = meshgrid(mincoord(1):maxcoord(1),mincoord(2):maxcoord(2),mincoord(3):maxcoord(3));
TR = triangulation(double(vmcmesh.H),vmcmesh.r); % create a matlab triangulation object from the points
locations = [gridx(:) gridy(:) gridz(:)]; % form a 2D matrix from all the grid points
indices = pointLocation(TR,locations); % query the indices of the tetrahedrons at grid points
indices(isnan(indices)) = 1; % set the grid points that do not belong to the mesh to point at the first element
gridval = reshape(solution.element_fluence(indices),size(gridx)); % get the values on the grid

Plot the solution

xmin = min(gridx(:)); ymin = min(gridy(:)); zmin = min(gridz(:));
xmax = max(gridx(:)); ymax = max(gridy(:)); zmax = max(gridz(:));

figure('rend','painters','pos',[10 10 1200 700])
hold on


hslice = surf(linspace(xmin,xmax,100),...
         linspace(ymin,ymax,100),...
         ones(100)*(zmax-zmin)/2.0); % form a slice

rotate(hslice,[0,1,0],90);
xd = get(hslice,'XData');
yd = get(hslice,'YData');
zd = get(hslice,'ZData');
delete(hslice);

colormap(jet);
h = slice(gridx,gridy,gridz,gridval,xd,yd,zd);
h.FaceColor = 'interp';
h.EdgeColor = 'none';
h.DiffuseStrength = 0.8;
trimesh(vmcmesh.BH,vmcmesh.r(:,1),vmcmesh.r(:,2),vmcmesh.r(:,3),'facecolor', 'r','FaceAlpha',0.2);
zlim([zmin zmax+1]);
view(70,40);
xlabel('x [mm]');
ylabel('y [mm]');
zlabel('z [mm]');
c=colorbar;
c.Label.String = 'Fluence [W/mm^2]';

[v i] = max(solution.element_fluence(:));