Skip to content

Commit dad3cec

Browse files
committed
Wrote python command line equivalent of Jupyter notebook scripts.
1 parent 61e7157 commit dad3cec

File tree

2 files changed

+208
-3
lines changed

2 files changed

+208
-3
lines changed

monte-carlo/analog-vs-caw-efficiency.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
# This is an example of python code using VTS to provide Monte Carlo solutions
2-
# for R(rho) using Analog and Continuous Absorption Weighting (CAW) random
3-
# walk processes.
1+
# Spatially-Resolved Reflectance Predictions for Analog versus CAW Simulations
2+
#
3+
# Goal: This exercise compares error estimates of spatially-resolved
4+
# reflectance using Analog versus Continuous Absorption Weighting (CAW) i
5+
# simulations.
46
#
57
# Import the Operating System so we can access the files for the VTS library
68
from pythonnet import load
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# Dependence of Fluence Predictions on the Number of Photons Simulated
2+
#
3+
# Goal: This exercise explores how fluence estimates change with the
4+
# number of photons simulated.
5+
#
6+
# Import the Operating System so we can access the files for the VTS library
7+
from pythonnet import load
8+
load('coreclr')
9+
import clr
10+
import os
11+
file = '../libraries/Vts.dll'
12+
clr.AddReference(os.path.abspath(file))
13+
import numpy as np
14+
import plotly.graph_objects as go
15+
from plotly.subplots import make_subplots
16+
# use matplotlib.pyplot
17+
import matplotlib as mpl
18+
import matplotlib.pyplot as plt
19+
from Vts import *
20+
from Vts.Common import *
21+
from Vts.Extensions import *
22+
from Vts.Modeling.Optimizers import *
23+
from Vts.Modeling.ForwardSolvers import *
24+
from Vts.SpectralMapping import *
25+
from Vts.Factories import *
26+
from Vts.MonteCarlo import *
27+
from Vts.MonteCarlo.Sources import *
28+
from Vts.MonteCarlo.Tissues import *
29+
from Vts.MonteCarlo.Detectors import *
30+
from Vts.MonteCarlo.Factories import *
31+
from Vts.MonteCarlo.PhotonData import *
32+
from Vts.MonteCarlo.PostProcessing import *
33+
from System import Array, Object, Double, Math
34+
# Setup the detector input for the simulation
35+
rhoStart = 0
36+
rhoStop = 10 # [mm]
37+
rhoCount = 101
38+
zStart = 0
39+
zStop = 10 # [mm]
40+
zCount = 101
41+
detectorRhoRange = DoubleRange(start=rhoStart, stop=rhoStop, number=rhoCount)
42+
detectorZRange = DoubleRange(start=zStart, stop=zStop, number=zCount)
43+
detectorInput = FluenceOfRhoAndZDetectorInput()
44+
detectorInput.Rho = detectorRhoRange
45+
detectorInput.Z = detectorZRange
46+
detectorInput.Name = "FluenceOfRhoAndZ"
47+
detectorInput.TallySecondMoment = True
48+
detectors = Array.CreateInstance(IDetectorInput,1)
49+
detectors[0] = detectorInput
50+
51+
# Setup the tissue input for the simulation
52+
regions = Array.CreateInstance(ITissueRegion, 3)
53+
regions[0] = LayerTissueRegion(zRange=DoubleRange(Double.NegativeInfinity, 0.0), op=OpticalProperties(mua=0.0, musp=1E-10, g=1.0, n=1.0)) # air
54+
regions[1] = LayerTissueRegion(zRange=DoubleRange(0.0, 100.0), op=OpticalProperties(mua=0.01, musp=1.0, g=0.8, n=1.4)) # tissue
55+
regions[2] = LayerTissueRegion(zRange=DoubleRange(100.0, Double.PositiveInfinity), op=OpticalProperties(mua=0.0, musp=1E-10, g=1.0, n=1.0)) # air
56+
57+
# Setup source
58+
sourceInput = DirectionalPointSourceInput()
59+
sourceInput.InitialTissueRegionIndex=0
60+
61+
# Setup number of photons simulated
62+
nPhot = [10, 100, 1000, 10000]
63+
FluenceArray = np.zeros((len(nPhot), (zCount - 1) * (rhoCount - 1)))
64+
RelativeErrorArray = np.zeros((len(nPhot), (zCount - 1) * (rhoCount-1)))
65+
66+
# plot 4 cases in grid
67+
fig, axes = plt.subplots(nrows=2,ncols=2)
68+
xLabel = "ρ [mm]"
69+
yLabel = "z [mm]"
70+
title = "log(Φ(ρ,z)) [mm-2]"
71+
# ignore divide by zero warning when calculating relative error
72+
np.seterr(divide='ignore', invalid='ignore')
73+
74+
for i in range(0, len(nPhot)):
75+
simulationOptions = SimulationOptions()
76+
simulationOptions.AbsorptionWeightingType = AbsorptionWeightingType.Analog # variation: set to Discrete
77+
# create a SimulationInput object to define the simulation
78+
simulationInput = SimulationInput()
79+
simulationInput.N = nPhot[i]
80+
simulationInput.OutputName = "MonteCarloFluence"
81+
simulationInput.DetectorInputs = detectors
82+
simulationInput.Options = simulationOptions
83+
simulationInput.Tissue = MultiLayerTissueInput(regions)
84+
# create the simulations
85+
simulation = MonteCarloSimulation(simulationInput)
86+
# run the simulations
87+
simulationOutput = simulation.Run()
88+
# determine standard deviation and plot the results using Plotly
89+
detectorResults = Array.CreateInstance(FluenceOfRhoAndZDetector, 1)
90+
detectorResults[0] = simulationOutput.ResultsDictionary["FluenceOfRhoAndZ"]
91+
Fluence = Array.CreateInstance(FluenceOfRhoAndZDetector, 1)
92+
RelativeError = Array.CreateInstance(FluenceOfRhoAndZDetector, 1)
93+
FluenceArray[i] = [f for f in detectorResults[0].Mean]
94+
SecondMoment = [s for s in detectorResults[0].SecondMoment]
95+
StandardDeviation = np.sqrt((SecondMoment - np.multiply(FluenceArray[i], FluenceArray[i]) / simulationInput.N))
96+
RelativeErrorArray[i] = np.divide(StandardDeviation, FluenceArray[i])
97+
98+
# plot fluence as a function of N, number of photons simulated
99+
# plot log of fluence and mirror fluence(rho,z) about rho=0 axis
100+
logFluence = [Math.Log(f) for f in FluenceArray[i]]
101+
# Convert to .NET array
102+
rhoDelta = detectorRhoRange.GetDelta()
103+
rhos = rhoStart + rhoDelta * np.arange(rhoCount - 1)
104+
# reverse and concatenate
105+
allRhos = np.concatenate((-rhos[::-1], rhos))
106+
zDelta = detectorZRange.GetDelta()
107+
zs = zStart + zDelta * np.arange(zCount - 1)
108+
fluenceRowsToPlot = np.array([logFluence[i:i+len(zs)] for i in range(0, len(logFluence), len(zs))])
109+
110+
colormap=mpl.colormaps['magma']
111+
cbar_ticks = [-6, -4, -2, 0]
112+
113+
if (i==0):
114+
im0=allFluenceRowsToPlot = np.concatenate((fluenceRowsToPlot[::-1], fluenceRowsToPlot))
115+
im0=axes[0,0].imshow(allFluenceRowsToPlot.T, vmin=-6, vmax=0)
116+
axes[0,0].set_title('log(Flu(ρ,z))[mm^-2]');
117+
axes[0,0].set_xlabel('ρ [mm]')
118+
axes[0,0].set_ylabel('z [mm]')
119+
axes[0,0].text(10, 90, 'N=10')
120+
cbar = fig.colorbar(im0, cmap=colormap, location='right', shrink=0.6, pad=0.05)
121+
cbar.set_ticks(cbar_ticks)
122+
if (i==1):
123+
im1=allFluenceRowsToPlot = np.concatenate((fluenceRowsToPlot[::-1], fluenceRowsToPlot))
124+
im1=axes[0,1].imshow(allFluenceRowsToPlot.T, vmin=-6, vmax=0)
125+
axes[0,1].set_title('log(Flu(ρ,z))[mm^-2]');
126+
axes[0,1].set_xlabel('ρ [mm]')
127+
axes[0,1].set_ylabel('z [mm]')
128+
axes[0,1].text(10, 90, 'N=100')
129+
cbar = fig.colorbar(im1, cmap=colormap, location='right', shrink=0.6, pad=0.05)
130+
cbar.set_ticks(cbar_ticks)
131+
if (i==2):
132+
im2=allFluenceRowsToPlot = np.concatenate((fluenceRowsToPlot[::-1], fluenceRowsToPlot))
133+
im2=axes[1,0].imshow(allFluenceRowsToPlot.T, vmin=-6, vmax=0)
134+
axes[1,0].set_title('log(Flu(ρ,z))[mm^-2]');
135+
axes[1,0].set_xlabel('ρ [mm]')
136+
axes[1,0].set_ylabel('z [mm]')
137+
axes[1,0].text(10, 90, 'N=1000')
138+
cbar = fig.colorbar(im2, cmap=colormap, location='right', shrink=0.6, pad=0.05)
139+
cbar.set_ticks(cbar_ticks)
140+
if (i==3):
141+
im3=allFluenceRowsToPlot = np.concatenate((fluenceRowsToPlot[::-1], fluenceRowsToPlot))
142+
im3=axes[1,1].imshow(allFluenceRowsToPlot.T, vmin=-6, vmax=0)
143+
axes[1,1].set_title('log(Flu(ρ,z))[mm^-2]');
144+
axes[1,1].set_xlabel('ρ [mm]')
145+
axes[1,1].set_ylabel('z [mm]')
146+
axes[1,1].text(10, 90, 'N=10000')
147+
cbar = fig.colorbar(im3, cmap=colormap, location='right', shrink=0.6, pad=0.05)
148+
cbar.set_ticks(cbar_ticks)
149+
150+
plt.savefig('fluence-vs-n.png')
151+
152+
# plot relative error as a function of N, the number of photons simulated
153+
# plot 4 cases in grid
154+
plt.clf() # clear fluence figure
155+
fig, axes = plt.subplots(nrows=2,ncols=2)
156+
xLabel = "ρ [mm]"
157+
yLabel = "z [mm]"
158+
title = "relerror(Φ(ρ,z))"
159+
160+
for i in range(0, len(nPhot)):
161+
# plot fluence relative error and mirror about rho=0 axis
162+
relativeError = [r for r in RelativeErrorArray[i]]
163+
relativeErrorRowsToPlot = np.array([relativeError[i:i+len(zs)] for i in range(0, len(relativeError), len(zs))])
164+
165+
colormap=mpl.colormaps['magma']
166+
cbar_ticks = [0.0, 0.5, 1.0]
167+
168+
if (i==0):
169+
im0=allRelativeErrorRowsToPlot = np.concatenate((relativeErrorRowsToPlot[::-1], relativeErrorRowsToPlot))
170+
im0=axes[0,0].imshow(allRelativeErrorRowsToPlot.T, vmin=0, vmax=1)
171+
axes[0,0].set_title('relerr(Flu(ρ,z))');
172+
axes[0,0].set_xlabel('ρ [mm]')
173+
axes[0,0].set_ylabel('z [mm]')
174+
axes[0,0].text(10, 90, 'N=10')
175+
cbar = fig.colorbar(im0, cmap=colormap, location='right', shrink=0.6, pad=0.05)
176+
cbar.set_ticks(cbar_ticks)
177+
if (i==1):
178+
im1=allRelativeErrorRowsToPlot = np.concatenate((relativeErrorRowsToPlot[::-1], relativeErrorRowsToPlot))
179+
im1=axes[0,1].imshow(allRelativeErrorRowsToPlot.T, vmin=0, vmax=1)
180+
axes[0,1].set_title('relerr(Flu(ρ,z))');
181+
axes[0,1].set_xlabel('ρ [mm]')
182+
axes[0,1].set_ylabel('z [mm]')
183+
axes[0,1].text(10, 90, 'N=100')
184+
cbar = fig.colorbar(im1, cmap=colormap, location='right', shrink=0.6, pad=0.05)
185+
if (i==2):
186+
im2=allRelativeErrorRowsToPlot = np.concatenate((relativeErrorRowsToPlot[::-1], relativeErrorRowsToPlot))
187+
im2=axes[1,0].imshow(allRelativeErrorRowsToPlot.T, vmin=0, vmax=1)
188+
axes[1,0].set_title('relerr(Flu(ρ,z))');
189+
axes[1,0].set_xlabel('ρ [mm]')
190+
axes[1,0].set_ylabel('z [mm]')
191+
axes[1,0].text(10, 90, 'N=1000')
192+
cbar = fig.colorbar(im2, cmap=colormap, location='right', shrink=0.6, pad=0.05)
193+
if (i==3):
194+
im3=allRelativeErrorRowsToPlot = np.concatenate((relativeErrorRowsToPlot[::-1], relativeErrorRowsToPlot))
195+
im3=axes[1,1].imshow(allRelativeErrorRowsToPlot.T, vmin=0, vmax=1)
196+
axes[1,1].set_title('relerr(Flu(ρ,z))');
197+
axes[1,1].set_xlabel('ρ [mm]')
198+
axes[1,1].set_ylabel('z [mm]')
199+
axes[1,1].text(10, 90, 'N=10000')
200+
cbar = fig.colorbar(im3, cmap=colormap, location='right', shrink=0.6, pad=0.05)
201+
202+
plt.savefig('relative-error-vs-n.png')
203+

0 commit comments

Comments
 (0)