Commit 5e1cbbabd929e9894e5ec50b1db86d3db588d730

Authored by dmayerich
1 parent 6f131540

Bug fixes. UI updates.

msinput.inp
... ... @@ -63,11 +63,11 @@ calculate_near_field
63 63 near_field_plane_coord
64 64 1
65 65 near_field_plane_position
66   -0.d0
  66 +0.0
67 67 near_field_plane_vertices
68   --20.d0,-20.d0,20.d0,20.d0
  68 +-20.0,-20.0,20.0,20.0
69 69 spacial_step_size
70   -.2d0
  70 +.20
71 71 polarization_angle_deg
72 72 0.d0
73 73 near_field_output_file
... ...
mstm-gui.py
... ... @@ -13,6 +13,8 @@ from PyQt4 import uic
13 13  
14 14 #Matplotlib libraries
15 15 import matplotlib.pyplot as plt
  16 +from matplotlib.patches import Patch
  17 +from pylab import *
16 18  
17 19 class GuiWindow(QtGui.QMainWindow):
18 20  
... ... @@ -22,37 +24,64 @@ class GuiWindow(QtGui.QMainWindow):
22 24 #update the Gui based on values in the parameters structure
23 25 self.ui.spinStartLambda.setValue(self.params.minLambda)
24 26 self.ui.spinEndLambda.setValue(self.params.maxLambda)
  27 + self.ui.spinNearFieldLambda.setValue(self.params.snapshotLambda)
25 28 self.ui.spinNumSamples.setValue(self.params.nSamples)
26 29 self.ui.spinNumSpheres.setValue(int(self.params['number_spheres']))
  30 + #near field stuff
  31 + self.ui.cmbPlaneSlice.setCurrentIndex(int(self.params['near_field_plane_coord']) - 1)
  32 + verts = self.params['near_field_plane_vertices']
  33 + self.ui.spinNearFieldWidth.setValue(verts[2] - verts[0])
  34 + self.ui.spinNearFieldHeight.setValue(verts[3] - verts[1])
  35 + self.ui.spinNearFieldSteps.setValue(self.params.nSteps)
27 36  
28 37 fi = QtCore.QFileInfo(self.params.matFilename)
29 38 self.ui.txtMaterial.setText(fi.baseName())
30 39  
31 40 #update global parameters for the dimer simulation
32   - self.ui.spinSpacing.setValue(d)
  41 + self.ui.spinSpacing.setValue(self.params.d)
  42 + self.ui.spinRadius.setValue(self.params.a)
33 43  
34 44 def getParams(self):
35 45 self.params.minLambda = self.ui.spinStartLambda.value()
36 46 self.params.maxLambda = self.ui.spinEndLambda.value()
  47 + self.params.snapshotLambda = self.ui.spinNearFieldLambda.value()
37 48 self.params.nSamples = self.ui.spinNumSamples.value()
38 49 self.params.nSpheres = self.ui.spinNumSpheres.value()
39   - self.params['incident_azimuth_angle_deg'] = self.ui.spinAlpha.value()
40   - self.params['incident_polar_angle_deg'] = self.ui.spinBeta.value()
41   - self.params.showOutput = self.ui.chkShowOutput.isChecked()
42   - self.params.inWater = self.ui.chkInWater.isChecked()
  50 +
  51 + #incident light properties
43 52 if self.ui.chkRandomOrientation.isChecked():
44 53 self.params['fixed_or_random_orientation'] = 1
45 54 else:
46 55 self.params['fixed_or_random_orientation'] = 0
  56 + self.params['incident_azimuth_angle_deg'] = self.ui.spinAlpha.value()
  57 + self.params['incident_polar_angle_deg'] = self.ui.spinBeta.value()
  58 + self.params['polarization_angle_deg'] = self.ui.spinGamma.value()
  59 +
  60 + self.params.showOutput = self.ui.chkShowOutput.isChecked()
47 61  
  62 + self.params.inWater = self.ui.chkInWater.isChecked()
  63 +
  64 +
  65 + #near field
  66 + if self.ui.chkNearField.isChecked():
  67 + self.params['calculate_near_field'] = 1
  68 + else:
  69 + self.params['calculate_near_field'] = 0
  70 + self.params['near_field_plane_coord'] = self.ui.cmbPlaneSlice.currentIndex() + 1
  71 + width = (self.ui.spinNearFieldWidth.value()/2)
  72 + height = (self.ui.spinNearFieldHeight.value()/2)
  73 + self.params['near_field_plane_vertices'] = [-width, -height, width, height]
  74 + dx = self.ui.spinNearFieldWidth.value() / (self.ui.spinNearFieldSteps.value() - 1)
  75 + self.params['spacial_step_size'] = dx
48 76  
49 77 #global parameters for dimers
50   - d = self.ui.spinSpacing.value()
51   -
  78 + self.params.d = self.ui.spinSpacing.value()
  79 + self.params.a = self.ui.spinRadius.value()
  80 +
52 81 return self.params
53 82  
54 83 def simulate(self):
55   - self.results = RunSimulation()
  84 + self.results = RunSimulation(True)
56 85  
57 86 #plot results of interest
58 87 wl = self.results['lambda']
... ... @@ -67,12 +96,58 @@ class GuiWindow(QtGui.QMainWindow):
67 96 else:
68 97 total = self.results['extinction_total']
69 98 plt.plot(wl, total, 'r-', label='extinction')
  99 +
  100 + #plot the near field maximum values if available
  101 +
  102 + if self.params['calculate_near_field']:
  103 + maxima = self.results.maxNearField
  104 + print(len(wl))
  105 + print(len(maxima))
  106 + plt.plot(wl, maxima)
  107 +
  108 +
70 109  
71 110 plt.legend(loc = 'upper left')
72 111 plt.ylabel('Extinction')
73 112 plt.xlabel('Wavelength (um)')
74 113 plt.show()
75 114  
  115 + def func3(self, x,y):
  116 + return (1- x/2 + x**5 + y**3)*exp(-x**2-y**2)
  117 +
  118 + def snapshot(self):
  119 +
  120 + self.results = RunSimulation(False)
  121 +
  122 + if self.params['calculate_near_field']:
  123 + #verts = self.params['near_field_plane_vertices']
  124 + #dx = (verts[2] - verts[0])/(self.params.nSteps)
  125 + #x = arange(verts[0], verts[2], dx)
  126 + #print(len(x))
  127 + #y = arange(verts[1], verts[3], dx)
  128 + #X, Y = meshgrid(x, y)
  129 + E = array(self.results.gridNearField)
  130 + #pcolor(X, Y, E, cmap=cm.RdBu)
  131 + #colorbar()
  132 + #axis([verts[0], verts[2], verts[1], verts[3]])
  133 +
  134 + pcolor(E, cmap=cm.RdBu)
  135 + colorbar()
  136 +
  137 + # make these smaller to increase the resolution
  138 + #dx, dy = 0.05, 0.05
  139 +
  140 + #x = arange(-3.0, 3.0001, dx)
  141 + #y = arange(-3.0, 3.0001, dy)
  142 + #X,Y = meshgrid(x, y)
  143 +
  144 + #Z = self.func3(X, Y)
  145 + #pcolor(X, Y, Z, cmap=cm.RdBu, vmax=abs(Z).max(), vmin=-abs(Z).max())
  146 + #colorbar()
  147 + #axis([-3,3,-3,3])
  148 +
  149 + show()
  150 +
76 151 def saveresults(self):
77 152 fileName = QtGui.QFileDialog.getSaveFileName(w, 'Save Spectral Results', '', 'DAT data files (*.dat)')
78 153 if fileName:
... ... @@ -85,6 +160,10 @@ class GuiWindow(QtGui.QMainWindow):
85 160  
86 161 fi = QtCore.QFileInfo(fileName)
87 162 self.ui.txtMaterial.setText(fi.baseName())
  163 +
  164 + def spherenum(self, i):
  165 + self.ui.tblSpheres.setRowCount(i)
  166 + print(i)
88 167  
89 168 def __init__(self):
90 169 QtGui.QWidget.__init__(self)
... ... @@ -100,10 +179,13 @@ class GuiWindow(QtGui.QMainWindow):
100 179 #display the UI
101 180 self.ui.show()
102 181  
103   - #simulation button
  182 + #controls
104 183 self.connect(self.ui.btnSimulate, QtCore.SIGNAL("clicked()"), self.simulate)
  184 + self.connect(self.ui.btnEvaluateNearField, QtCore.SIGNAL("clicked()"), self.snapshot)
105 185 self.connect(self.ui.mnuSaveResults, QtCore.SIGNAL("triggered()"), self.saveresults)
106 186 self.connect(self.ui.mnuLoadMaterial, QtCore.SIGNAL("triggered()"), self.loadmaterial)
  187 + self.connect(self.ui.spinNumSpheres, QtCore.SIGNAL("valueChanged(int)"), self.spherenum)
  188 +
107 189  
108 190 class ProgressBar(QtGui.QWidget):
109 191 def __init__(self, parent=None, total=20):
... ... @@ -124,7 +206,7 @@ class ProgressBar(QtGui.QWidget):
124 206 self.progressbar.setValue(val)
125 207  
126 208  
127   -def RunSimulation():
  209 +def RunSimulation(spectralSim = True):
128 210  
129 211 #set the parameters based on the UI
130 212 parameters = w.getParams()
... ... @@ -138,10 +220,15 @@ def RunSimulation():
138 220 if parameters.inWater:
139 221 material.addSolution(1.33)
140 222  
141   - #range for simulation
142   - minLambda = parameters.minLambda
143   - maxLambda = parameters.maxLambda
144   - nSamples = parameters.nSamples
  223 + #for a spectral simulation, set the range and number of samples
  224 + if spectralSim:
  225 + minLambda = parameters.minLambda
  226 + maxLambda = parameters.maxLambda
  227 + nSamples = parameters.nSamples
  228 + else:
  229 + minLambda = parameters.snapshotLambda
  230 + maxLambda = parameters.snapshotLambda
  231 + nSamples = 1
145 232  
146 233 #store the simulation results
147 234 results = SimParserClass(parameters)
... ... @@ -153,7 +240,10 @@ def RunSimulation():
153 240 #for each wavelength in the material
154 241 for i in range(nSamples):
155 242  
156   - l = minLambda + i*(maxLambda - minLambda)/(nSamples - 1)
  243 + if i == 0:
  244 + l = minLambda
  245 + else:
  246 + l = minLambda + i*(maxLambda - minLambda)/(nSamples - 1)
157 247  
158 248  
159 249  
... ... @@ -164,16 +254,16 @@ def RunSimulation():
164 254 parameters['imag_ref_index_scale_factor'] = n.imag
165 255 parameters['length_scale_factor'] = (2.0 * 3.14159)/l
166 256 parameters['scattering_plane_angle_deg'] = gamma;
167   - #parameters['fixed_or_random_orientation'] = 0
168   - #print(parameters['fixed_or_random_orientation'])
169   -
  257 + parameters['near_field_output_data'] = 0
170 258  
  259 + a = parameters.a;
  260 + d = parameters.d;
171 261 parameters.clearSpheres()
172 262 parameters.addSphere(a, -(d + 2*a)/2, 0, 0)
173 263 parameters.addSphere(a, (d + 2*a)/2, 0, 0)
174 264  
175 265 #save the scripted input file
176   - parameters.saveFile('scriptParams.inp')
  266 + parameters.saveFile(l, 'scriptParams.inp')
177 267  
178 268 #run the binary
179 269 from subprocess import call
... ... @@ -183,11 +273,15 @@ def RunSimulation():
183 273 devnull = open('/dev/null', 'w')
184 274 call(["./ms-tmatrix", "scriptParams.inp"], stdout=devnull)
185 275  
  276 + #parse the simulation results
186 277 results.parseSimFile(l, 'test.dat')
  278 +
  279 + if parameters['calculate_near_field']:
  280 + results.parseNearField('nf-temp.dat')
  281 +
187 282  
188 283 #update the progress bar
189 284 pbar.update_progressbar(i+1)
190   - print(i+1)
191 285  
192 286 #return the results
193 287 return results;
... ... @@ -197,10 +291,7 @@ def RunSimulation():
197 291  
198 292  
199 293  
200   -#sphere radii
201   -a = 0.025
202   -#distance between spheres
203   -d = 0.002
  294 +
204 295 #incident light directions
205 296 alpha = 0
206 297 beta = 0
... ...
mstm_guiwindow.ui
... ... @@ -6,27 +6,14 @@
6 6 <rect>
7 7 <x>0</x>
8 8 <y>0</y>
9   - <width>599</width>
10   - <height>418</height>
  9 + <width>590</width>
  10 + <height>627</height>
11 11 </rect>
12 12 </property>
13 13 <property name="windowTitle">
14 14 <string>Spectral Multi-Sphere T-Matrix Simulation</string>
15 15 </property>
16 16 <widget class="QWidget" name="centralwidget">
17   - <widget class="QPushButton" name="btnSimulate">
18   - <property name="geometry">
19   - <rect>
20   - <x>400</x>
21   - <y>70</y>
22   - <width>89</width>
23   - <height>23</height>
24   - </rect>
25   - </property>
26   - <property name="text">
27   - <string>Simulate</string>
28   - </property>
29   - </widget>
30 17 <widget class="QLabel" name="label_7">
31 18 <property name="geometry">
32 19 <rect>
... ... @@ -123,7 +110,7 @@
123 110 </rect>
124 111 </property>
125 112 <property name="text">
126   - <string>Wavelengths(um)</string>
  113 + <string>Wavelengths (um)</string>
127 114 </property>
128 115 <property name="alignment">
129 116 <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
... ... @@ -176,7 +163,7 @@
176 163 <property name="geometry">
177 164 <rect>
178 165 <x>10</x>
179   - <y>150</y>
  166 + <y>270</y>
180 167 <width>361</width>
181 168 <height>91</height>
182 169 </rect>
... ... @@ -187,8 +174,8 @@
187 174 <widget class="QLabel" name="label_6">
188 175 <property name="geometry">
189 176 <rect>
190   - <x>220</x>
191   - <y>60</y>
  177 + <x>330</x>
  178 + <y>30</y>
192 179 <width>31</width>
193 180 <height>21</height>
194 181 </rect>
... ... @@ -216,9 +203,9 @@
216 203 <widget class="QLabel" name="label_4">
217 204 <property name="geometry">
218 205 <rect>
219   - <x>0</x>
  206 + <x>10</x>
220 207 <y>30</y>
221   - <width>111</width>
  208 + <width>71</width>
222 209 <height>21</height>
223 210 </rect>
224 211 </property>
... ... @@ -247,23 +234,55 @@
247 234 </widget>
248 235 <widget class="QSpinBox" name="spinNumSpheres">
249 236 <property name="enabled">
250   - <bool>false</bool>
  237 + <bool>true</bool>
251 238 </property>
252 239 <property name="geometry">
253 240 <rect>
254   - <x>120</x>
  241 + <x>90</x>
255 242 <y>30</y>
256 243 <width>55</width>
257 244 <height>22</height>
258 245 </rect>
259 246 </property>
260 247 </widget>
  248 + <widget class="QLabel" name="label_10">
  249 + <property name="geometry">
  250 + <rect>
  251 + <x>170</x>
  252 + <y>30</y>
  253 + <width>51</width>
  254 + <height>21</height>
  255 + </rect>
  256 + </property>
  257 + <property name="text">
  258 + <string>Radius</string>
  259 + </property>
  260 + <property name="alignment">
  261 + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
  262 + </property>
  263 + </widget>
  264 + <widget class="QDoubleSpinBox" name="spinRadius">
  265 + <property name="geometry">
  266 + <rect>
  267 + <x>230</x>
  268 + <y>30</y>
  269 + <width>91</width>
  270 + <height>22</height>
  271 + </rect>
  272 + </property>
  273 + <property name="decimals">
  274 + <number>4</number>
  275 + </property>
  276 + <property name="singleStep">
  277 + <double>0.001000000000000</double>
  278 + </property>
  279 + </widget>
261 280 </widget>
262 281 <widget class="QGroupBox" name="groupBox_3">
263 282 <property name="geometry">
264 283 <rect>
265 284 <x>10</x>
266   - <y>250</y>
  285 + <y>150</y>
267 286 <width>361</width>
268 287 <height>111</height>
269 288 </rect>
... ... @@ -274,8 +293,8 @@
274 293 <widget class="QLabel" name="label_8">
275 294 <property name="geometry">
276 295 <rect>
277   - <x>20</x>
278   - <y>20</y>
  296 + <x>0</x>
  297 + <y>50</y>
279 298 <width>91</width>
280 299 <height>21</height>
281 300 </rect>
... ... @@ -290,8 +309,8 @@
290 309 <widget class="QDoubleSpinBox" name="spinAlpha">
291 310 <property name="geometry">
292 311 <rect>
293   - <x>120</x>
294   - <y>20</y>
  312 + <x>100</x>
  313 + <y>50</y>
295 314 <width>91</width>
296 315 <height>22</height>
297 316 </rect>
... ... @@ -299,6 +318,9 @@
299 318 <property name="decimals">
300 319 <number>3</number>
301 320 </property>
  321 + <property name="maximum">
  322 + <double>180.000000000000000</double>
  323 + </property>
302 324 <property name="singleStep">
303 325 <double>0.100000000000000</double>
304 326 </property>
... ... @@ -306,8 +328,8 @@
306 328 <widget class="QLabel" name="label_9">
307 329 <property name="geometry">
308 330 <rect>
309   - <x>20</x>
310   - <y>50</y>
  331 + <x>0</x>
  332 + <y>80</y>
311 333 <width>91</width>
312 334 <height>21</height>
313 335 </rect>
... ... @@ -322,8 +344,71 @@
322 344 <widget class="QDoubleSpinBox" name="spinBeta">
323 345 <property name="geometry">
324 346 <rect>
325   - <x>120</x>
326   - <y>50</y>
  347 + <x>100</x>
  348 + <y>80</y>
  349 + <width>91</width>
  350 + <height>22</height>
  351 + </rect>
  352 + </property>
  353 + <property name="decimals">
  354 + <number>3</number>
  355 + </property>
  356 + <property name="maximum">
  357 + <double>180.000000000000000</double>
  358 + </property>
  359 + <property name="singleStep">
  360 + <double>0.100000000000000</double>
  361 + </property>
  362 + </widget>
  363 + <widget class="QLabel" name="label_15">
  364 + <property name="geometry">
  365 + <rect>
  366 + <x>50</x>
  367 + <y>20</y>
  368 + <width>111</width>
  369 + <height>21</height>
  370 + </rect>
  371 + </property>
  372 + <property name="font">
  373 + <font>
  374 + <weight>75</weight>
  375 + <bold>true</bold>
  376 + </font>
  377 + </property>
  378 + <property name="text">
  379 + <string>Light Position</string>
  380 + </property>
  381 + <property name="alignment">
  382 + <set>Qt::AlignCenter</set>
  383 + </property>
  384 + </widget>
  385 + <widget class="QLabel" name="label_16">
  386 + <property name="geometry">
  387 + <rect>
  388 + <x>230</x>
  389 + <y>20</y>
  390 + <width>111</width>
  391 + <height>21</height>
  392 + </rect>
  393 + </property>
  394 + <property name="font">
  395 + <font>
  396 + <weight>75</weight>
  397 + <bold>true</bold>
  398 + </font>
  399 + </property>
  400 + <property name="text">
  401 + <string>Polarization</string>
  402 + </property>
  403 + <property name="alignment">
  404 + <set>Qt::AlignCenter</set>
  405 + </property>
  406 + </widget>
  407 + <widget class="QDoubleSpinBox" name="spinGamma">
  408 + <property name="geometry">
  409 + <rect>
  410 + <x>240</x>
  411 + <y>70</y>
327 412 <width>91</width>
328 413 <height>22</height>
329 414 </rect>
... ... @@ -331,36 +416,294 @@
331 416 <property name="decimals">
332 417 <number>3</number>
333 418 </property>
  419 + <property name="maximum">
  420 + <double>180.000000000000000</double>
  421 + </property>
334 422 <property name="singleStep">
335 423 <double>0.100000000000000</double>
336 424 </property>
337 425 </widget>
  426 + <widget class="QLabel" name="label_17">
  427 + <property name="geometry">
  428 + <rect>
  429 + <x>240</x>
  430 + <y>50</y>
  431 + <width>101</width>
  432 + <height>21</height>
  433 + </rect>
  434 + </property>
  435 + <property name="text">
  436 + <string>gamma (deg.)</string>
  437 + </property>
  438 + <property name="alignment">
  439 + <set>Qt::AlignCenter</set>
  440 + </property>
  441 + </widget>
338 442 </widget>
339   - <widget class="QCheckBox" name="chkShowOutput">
  443 + <widget class="QCheckBox" name="chkInWater">
340 444 <property name="geometry">
341 445 <rect>
342   - <x>400</x>
343   - <y>120</y>
344   - <width>131</width>
  446 + <x>350</x>
  447 + <y>20</y>
  448 + <width>83</width>
345 449 <height>19</height>
346 450 </rect>
347 451 </property>
348 452 <property name="text">
349   - <string>MS-TM output</string>
  453 + <string>in water</string>
350 454 </property>
351 455 </widget>
352   - <widget class="QCheckBox" name="chkInWater">
  456 + <widget class="QGroupBox" name="groupBox_4">
353 457 <property name="geometry">
354 458 <rect>
355   - <x>350</x>
356   - <y>20</y>
357   - <width>83</width>
358   - <height>19</height>
  459 + <x>390</x>
  460 + <y>250</y>
  461 + <width>181</width>
  462 + <height>231</height>
359 463 </rect>
360 464 </property>
361   - <property name="text">
362   - <string>in water</string>
  465 + <property name="title">
  466 + <string>Near Field</string>
363 467 </property>
  468 + <widget class="QCheckBox" name="chkNearField">
  469 + <property name="geometry">
  470 + <rect>
  471 + <x>20</x>
  472 + <y>30</y>
  473 + <width>151</width>
  474 + <height>19</height>
  475 + </rect>
  476 + </property>
  477 + <property name="text">
  478 + <string>Compute Near Field</string>
  479 + </property>
  480 + </widget>
  481 + <widget class="QComboBox" name="cmbPlaneSlice">
  482 + <property name="geometry">
  483 + <rect>
  484 + <x>70</x>
  485 + <y>60</y>
  486 + <width>61</width>
  487 + <height>22</height>
  488 + </rect>
  489 + </property>
  490 + <item>
  491 + <property name="text">
  492 + <string>Y - Z</string>
  493 + </property>
  494 + </item>
  495 + <item>
  496 + <property name="text">
  497 + <string>Z - X</string>
  498 + </property>
  499 + </item>
  500 + <item>
  501 + <property name="text">
  502 + <string>X - Y</string>
  503 + </property>
  504 + </item>
  505 + </widget>
  506 + <widget class="QDoubleSpinBox" name="spinNearFieldWidth">
  507 + <property name="geometry">
  508 + <rect>
  509 + <x>70</x>
  510 + <y>100</y>
  511 + <width>62</width>
  512 + <height>22</height>
  513 + </rect>
  514 + </property>
  515 + <property name="singleStep">
  516 + <double>0.100000000000000</double>
  517 + </property>
  518 + </widget>
  519 + <widget class="QLabel" name="label_12">
  520 + <property name="geometry">
  521 + <rect>
  522 + <x>20</x>
  523 + <y>100</y>
  524 + <width>41</width>
  525 + <height>21</height>
  526 + </rect>
  527 + </property>
  528 + <property name="text">
  529 + <string>width</string>
  530 + </property>
  531 + <property name="alignment">
  532 + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
  533 + </property>
  534 + </widget>
  535 + <widget class="QLabel" name="label_13">
  536 + <property name="geometry">
  537 + <rect>
  538 + <x>20</x>
  539 + <y>140</y>
  540 + <width>41</width>
  541 + <height>21</height>
  542 + </rect>
  543 + </property>
  544 + <property name="text">
  545 + <string>height</string>
  546 + </property>
  547 + <property name="alignment">
  548 + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
  549 + </property>
  550 + </widget>
  551 + <widget class="QDoubleSpinBox" name="spinNearFieldHeight">
  552 + <property name="geometry">
  553 + <rect>
  554 + <x>70</x>
  555 + <y>140</y>
  556 + <width>62</width>
  557 + <height>22</height>
  558 + </rect>
  559 + </property>
  560 + <property name="singleStep">
  561 + <double>0.100000000000000</double>
  562 + </property>
  563 + </widget>
  564 + <widget class="QLabel" name="label_14">
  565 + <property name="geometry">
  566 + <rect>
  567 + <x>20</x>
  568 + <y>180</y>
  569 + <width>41</width>
  570 + <height>21</height>
  571 + </rect>
  572 + </property>
  573 + <property name="text">
  574 + <string>steps</string>
  575 + </property>
  576 + <property name="alignment">
  577 + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
  578 + </property>
  579 + </widget>
  580 + <widget class="QSpinBox" name="spinNearFieldSteps">
  581 + <property name="geometry">
  582 + <rect>
  583 + <x>70</x>
  584 + <y>180</y>
  585 + <width>61</width>
  586 + <height>22</height>
  587 + </rect>
  588 + </property>
  589 + <property name="maximum">
  590 + <number>9999</number>
  591 + </property>
  592 + </widget>
  593 + </widget>
  594 + <widget class="QGroupBox" name="groupBox_5">
  595 + <property name="geometry">
  596 + <rect>
  597 + <x>390</x>
  598 + <y>50</y>
  599 + <width>171</width>
  600 + <height>191</height>
  601 + </rect>
  602 + </property>
  603 + <property name="title">
  604 + <string>Simulate</string>
  605 + </property>
  606 + <widget class="QCheckBox" name="chkShowOutput">
  607 + <property name="geometry">
  608 + <rect>
  609 + <x>40</x>
  610 + <y>140</y>
  611 + <width>101</width>
  612 + <height>19</height>
  613 + </rect>
  614 + </property>
  615 + <property name="text">
  616 + <string>MS-TM output</string>
  617 + </property>
  618 + </widget>
  619 + <widget class="QPushButton" name="btnEvaluateNearField">
  620 + <property name="geometry">
  621 + <rect>
  622 + <x>10</x>
  623 + <y>100</y>
  624 + <width>151</width>
  625 + <height>23</height>
  626 + </rect>
  627 + </property>
  628 + <property name="text">
  629 + <string>Simulate Wavelength</string>
  630 + </property>
  631 + </widget>
  632 + <widget class="QPushButton" name="btnSimulate">
  633 + <property name="geometry">
  634 + <rect>
  635 + <x>10</x>
  636 + <y>20</y>
  637 + <width>151</width>
  638 + <height>23</height>
  639 + </rect>
  640 + </property>
  641 + <property name="text">
  642 + <string>Simulate Spectrum</string>
  643 + </property>
  644 + </widget>
  645 + <widget class="QDoubleSpinBox" name="spinNearFieldLambda">
  646 + <property name="geometry">
  647 + <rect>
  648 + <x>40</x>
  649 + <y>70</y>
  650 + <width>91</width>
  651 + <height>22</height>
  652 + </rect>
  653 + </property>
  654 + </widget>
  655 + <widget class="QLabel" name="label_11">
  656 + <property name="geometry">
  657 + <rect>
  658 + <x>30</x>
  659 + <y>50</y>
  660 + <width>111</width>
  661 + <height>21</height>
  662 + </rect>
  663 + </property>
  664 + <property name="text">
  665 + <string>Wavelength (um)</string>
  666 + </property>
  667 + <property name="alignment">
  668 + <set>Qt::AlignCenter</set>
  669 + </property>
  670 + </widget>
  671 + </widget>
  672 + <widget class="QTableWidget" name="tblSpheres">
  673 + <property name="geometry">
  674 + <rect>
  675 + <x>10</x>
  676 + <y>390</y>
  677 + <width>361</width>
  678 + <height>181</height>
  679 + </rect>
  680 + </property>
  681 + <attribute name="horizontalHeaderDefaultSectionSize">
  682 + <number>89</number>
  683 + </attribute>
  684 + <attribute name="verticalHeaderDefaultSectionSize">
  685 + <number>30</number>
  686 + </attribute>
  687 + <column>
  688 + <property name="text">
  689 + <string>radius</string>
  690 + </property>
  691 + </column>
  692 + <column>
  693 + <property name="text">
  694 + <string>pX</string>
  695 + </property>
  696 + </column>
  697 + <column>
  698 + <property name="text">
  699 + <string>y</string>
  700 + </property>
  701 + </column>
  702 + <column>
  703 + <property name="text">
  704 + <string>z</string>
  705 + </property>
  706 + </column>
364 707 </widget>
365 708 </widget>
366 709 <widget class="QMenuBar" name="menubar">
... ... @@ -368,7 +711,7 @@
368 711 <rect>
369 712 <x>0</x>
370 713 <y>0</y>
371   - <width>599</width>
  714 + <width>590</width>
372 715 <height>22</height>
373 716 </rect>
374 717 </property>
... ...
mstm_parameters.py
... ... @@ -2,9 +2,17 @@ class ParameterClass:
2 2 #minimum and maximum wavelengths for the simulation
3 3 minLambda = 0.300
4 4 maxLambda = 0.700
  5 + snapshotLambda = 0.300
5 6 #number of spectral samples
6 7 nSamples = 40
7 8  
  9 + #spatial samples
  10 + nSteps = 100
  11 +
  12 + #sphere size and separation
  13 + a = 0.025
  14 + d = 0.005
  15 +
8 16 #material file name
9 17 matFilename = 'etaSilver.txt'
10 18 #are the sphere's in water?
... ... @@ -25,7 +33,7 @@ class ParameterClass:
25 33 return self.paramDict[key];
26 34  
27 35 def __setitem__(self, key, value):
28   - self.paramDict[key] = str(value);
  36 + self.paramDict[key] = value;
29 37  
30 38 def clearSpheres(self):
31 39 self.sphereList = []
... ... @@ -40,7 +48,8 @@ class ParameterClass:
40 48  
41 49 while 1:
42 50 key = inpFID.readline().strip()
43   -
  51 +
  52 +
44 53 #deal with sphere sizes and positions
45 54 if key == 'sphere_sizes_and_positions':
46 55  
... ... @@ -57,13 +66,24 @@ class ParameterClass:
57 66 break
58 67 elif key == 'end_of_options':
59 68 break
  69 + #deal with the near field plane
  70 + elif key == 'near_field_plane_vertices':
  71 + value = inpFID.readline().strip()
  72 + #self.paramDict[key] = list(map(float, value.split(',')))
  73 + self.paramDict[key] = [-1, -1, 1, 1]
  74 +
60 75 else:
61 76 value = inpFID.readline().strip()
62 77 self.paramDict[key] = value
  78 +
  79 + #update the length scale factor to deal with the UI
  80 + self.paramDict['length_scale_factor'] = (2.0 * 3.14159)/self.snapshotLambda
63 81  
64 82 inpFID.close()
65 83  
66   - def saveFile(self, fileName):
  84 + def saveFile(self, l, fileName):
  85 +
  86 + #print(self)
67 87  
68 88 #open the output file
69 89 outFID = open(fileName, 'w')
... ... @@ -71,7 +91,20 @@ class ParameterClass:
71 91 #write the parameters
72 92 for key in self.paramDict.keys():
73 93 outFID.write(key + '\n')
74   - outFID.write(self.paramDict[key] + '\n')
  94 +
  95 + #deal with the near field plane
  96 + if key == 'near_field_plane_vertices':
  97 + #these have to be scaled by the length scale factor
  98 + ls = (2 * 3.14159)/l
  99 + v = self.paramDict[key]
  100 + outFID.write(str(v[0]*ls) + ',' + str(v[1]*ls) + ',' + str(v[2]*ls) + ',' + str(v[3]*ls) + '\n')
  101 + elif key == 'spacial_step_size':
  102 + ls = (2 * 3.14159)/l
  103 + dx = self.paramDict[key] * ls
  104 + outFID.write(str(dx) + '\n')
  105 +
  106 + else:
  107 + outFID.write(str(self.paramDict[key]) + '\n')
75 108  
76 109 #write the spheres
77 110 outFID.write("sphere_sizes_and_positions\n")
... ... @@ -86,7 +119,12 @@ class ParameterClass:
86 119 #print(self.paramDict)
87 120 result = ""
88 121 for key in self.paramDict.keys():
89   - result += key + ": " + self.paramDict[key] + '\n'
  122 + #deal with the near field plane
  123 + if key == 'near_field_plane_vertices':
  124 + v = map(str, self.paramDict[key])
  125 + result += key + ": " + v[0] + ',' + v[1] + ',' + v[2] + ',' + v[3] + '\n'
  126 + else:
  127 + result += key + ": " + str(self.paramDict[key]) + '\n'
90 128  
91 129 result += "\n"
92 130 result += "Spheres:\n"
... ...
mstm_simparser.py
  1 +from pylab import *
  2 +
1 3 class SimParserClass:
2 4  
3 5 simResults = dict()
  6 +
  7 + sxNearField = 0
  8 + syNearField = 0
  9 + intersectedNearField = 0
  10 +
  11 + #near field data
  12 + gridNearField = []
  13 + maxNearField = []
  14 +
4 15  
5 16 def __init__(self, parameters):
6 17  
... ... @@ -12,9 +23,11 @@ class SimParserClass:
12 23 self.simResults['extinction_parallel'] = list()
13 24 self.simResults['extinction_perpendicular'] = list()
14 25 self.simResults['extinction_total'] = list()
15   -
16   -
17   -
  26 +
  27 + self.gridNearField = []
  28 + self.maxNearField = []
  29 +
  30 +
18 31 def parseSimFile(self, l, fileName):
19 32 self.simResults['lambda'].append(l)
20 33 inFile = open(fileName, 'r')
... ... @@ -38,13 +51,39 @@ class SimParserClass:
38 51 self.simResults['extinction_perpendicular'].append(values[0])
39 52  
40 53 else:
41   - #print('making it here')
42   - #print(self.params['fixed_or_random_orientation'])
43 54 if line == 'scattering matrix elements':
44 55 break
45 56 elif line == 'total ext, abs, scat efficiencies, w.r.t. xv, and asym. parm':
46 57 values = inFile.readline().strip().split(' ')
47 58 self.simResults['extinction_total'].append(values[0])
  59 +
  60 + def parseNearField(self, fileName):
  61 +
  62 + inFile = open(fileName, 'r')
  63 +
  64 + #get the size of the near field grid
  65 + line = inFile.readline().strip()
  66 + self.sxNearField, self.syNearField = map(int, line.split())
  67 +
  68 + #get the number of spheres that are intersected
  69 + line = inFile.readline().strip()
  70 + self.intersectedNearField = int(line)
  71 +
  72 + #process intersections here-----------
  73 +
  74 +
  75 + #get the field values
  76 + self.gridNearField = []
  77 + for y in range(self.syNearField):
  78 + self.gridNearField.append([])
  79 + for x in range(self.sxNearField):
  80 + line = inFile.readline().strip()
  81 + values = map(float, line.split())
  82 + self.gridNearField[y].append(values[2])
  83 +
  84 + E = array(self.gridNearField)
  85 + self.maxNearField.append(pow(E.max(), 2))
  86 +
48 87  
49 88 def saveFile(self, fileName):
50 89 outFile = open(fileName, 'w')
... ... @@ -58,9 +97,14 @@ class SimParserClass:
58 97 result = '';
59 98  
60 99 for i in range(len(self.simResults['lambda'])):
61   - result += str(self.simResults['lambda'][i]) + '\t'
62   - result += str(self.simResults['extinction_unpolarized'][i]) + '\t'
63   - result += str(self.simResults['extinction_parallel'][i]) + '\t'
64   - result += str(self.simResults['extinction_perpendicular'][i]) + '\n'
65   -
  100 + result += str(self.simResults['lambda'][i])
  101 + result += '\t' + str(self.simResults['extinction_unpolarized'][i])
  102 + result += '\t' + str(self.simResults['extinction_parallel'][i])
  103 + result += '\t' + str(self.simResults['extinction_perpendicular'][i])
  104 +
  105 + #parse the near field if it is included in the simulation
  106 + if int(parameters['calculate_near_field']) == 1:
  107 + result += '\t' + str(maxNearField)
  108 +
  109 + result += '\n'
66 110 return result
... ...