1 | #pragma rtGlobals=1 // Use modern global access method. |
---|
2 | |
---|
3 | // this is a file with all of the functions that can be used to |
---|
4 | // script the MC simulation of data |
---|
5 | // 1D will also be supported, unless I can find a reason not to support this. |
---|
6 | // |
---|
7 | // there will be a lot of utility functions to "move" the parts of an instrument that |
---|
8 | // are "moveable" into different configurations. The aim is to have this appear as |
---|
9 | // much like running an experiment as possible. |
---|
10 | // |
---|
11 | // |
---|
12 | // The basic cycle: |
---|
13 | // |
---|
14 | // 1) plot the model function, and set the coefficients to what you want |
---|
15 | // |
---|
16 | // 2) set (and save) as many configurations as you like -picking ones that are most appropriate for the sample scattering |
---|
17 | // |
---|
18 | // Sim_SaveConfiguration(waveStr) |
---|
19 | // |
---|
20 | // 3) simulate the sample scattering at your configurations for specified times. The 1D count rate |
---|
21 | // should match fairly well to the 2D count rate. (Check this for low/high incoherent levels) |
---|
22 | //-or- |
---|
23 | // 4) run everything for a short time (say 1s to 10s) to get the count rates |
---|
24 | // - this will actually save the files - just like a real experiment. This is like step 6, but with short count times. |
---|
25 | // |
---|
26 | // 5) with the sample count rates, find the optimal count times |
---|
27 | // |
---|
28 | // OptimalCount(samCR,empCR) |
---|
29 | // |
---|
30 | // 6) Write a function to "run" the samples at configurations and count times. Don't forget to simulate |
---|
31 | // the transmissions. (See the examples below). Copy the function to a new procedure window, rename it, |
---|
32 | // and edit it there as you wish. |
---|
33 | // |
---|
34 | // ListSASCALCConfigs() will print out the list of configurations |
---|
35 | // |
---|
36 | // 7) Then with the optimal count times, do a dry run to see how long the whole simulation would take. |
---|
37 | // |
---|
38 | // Sim_DryRun(funcStr) |
---|
39 | // |
---|
40 | // 8) Then if that's OK, run the full simulation |
---|
41 | // |
---|
42 | // Your function here() |
---|
43 | // |
---|
44 | // 9) If it's 1D data, use NSORT to combine. If it's 2D data, reduce as usual. Be sure to skip the detector |
---|
45 | // efficiency correction, and set the dead time to a tiny value so that it won't have any |
---|
46 | // effect (since the detector CR is fictionally high, and the detector is perfect): |
---|
47 | // |
---|
48 | // Sim_SetDeadTimeTiny() |
---|
49 | // |
---|
50 | // When you have a lot of 1D waves to combine, and they are not numbered like in a real reduction |
---|
51 | // experiment, see: |
---|
52 | // |
---|
53 | // MakeCombineTable_byName() |
---|
54 | // DoCombineFiles_byName(lowQfile,medQfile,hiQfile,saveName) (in NSORT.ipf) |
---|
55 | // |
---|
56 | // this works with 1, 2, or 3 data files |
---|
57 | // |
---|
58 | |
---|
59 | |
---|
60 | // In general, when setting up a simulation, it's easier to set up sample conditions for a particular |
---|
61 | // sample, and loop through the configurations. If you want your 2D data to "look" like a typical |
---|
62 | // experiment, then you'll need to simulate each different sample at one configuration, then "move" |
---|
63 | // to a different configuration and loop through the samples again. Somewhat more cumbersome, all to |
---|
64 | // get the file catalog to be "grouped" like a real SANS experiment. |
---|
65 | |
---|
66 | |
---|
67 | // |
---|
68 | // Important - in the reduction process, set the dead time correction to something |
---|
69 | // really small, say 10^-15 |
---|
70 | // |
---|
71 | // see Sim_SetDeadTimeTiny() |
---|
72 | |
---|
73 | // |
---|
74 | // TODO: |
---|
75 | // x- need to update the 1D writer to allow a name to be passed in, rather than |
---|
76 | // always using the dialog |
---|
77 | // x- fill in the "RunSample" functions |
---|
78 | // |
---|
79 | // -- I need a little panel to control all of this, and get the information, just |
---|
80 | // like setting up a real experiment. Or maybe not. Maybe better to keep some of this |
---|
81 | // hidden. |
---|
82 | // -- It would be nice to be able to automatically do the sum_model to add the 2D empty cell contribution |
---|
83 | // For some experiments it's quite useful to see the level of this contribution, rather than |
---|
84 | // the completely clean simulation. |
---|
85 | // -- in this file, clearly separate the examples from the utility functions |
---|
86 | // -- get a function list of everything, and document what each does (if not obvious) |
---|
87 | // -- step by step comments of one of the examples (1D and 2D) are probably the most useful |
---|
88 | // -- "dry run" function to estimate the total simulation time for 2D. (? set all monitor counts to 1000 |
---|
89 | // or whatever I use to get other estimates, and then run through everything to get estimated times) |
---|
90 | // |
---|
91 | // set the global: |
---|
92 | // NVAR g_estimateOnly = root:Packages:NIST:SAS:g_estimateOnly // == 1 for just a time estimate, == 0 (default) to do the simulation |
---|
93 | // and then do the dry run |
---|
94 | // |
---|
95 | // |
---|
96 | // ----- transmission really doesn't work in the simulation... |
---|
97 | // -- add function to simulate transmission in 2D by saving a "Trans" configuration |
---|
98 | // and automatically using that. Currently the trans is already written to the file |
---|
99 | // x- would also need a function to simulate an empty beam measurement to rescale the |
---|
100 | // transmissions. (use the model given, set scale (w[0] to something really small) |
---|
101 | // -- or better, use the empty cell function that is guaranteed to have coefficients that are |
---|
102 | // well behaved - and I can set/reset them to get a proper "empty beam" |
---|
103 | // |
---|
104 | // |
---|
105 | // -- scattering from an empty cell is NOT provided in 2D |
---|
106 | |
---|
107 | Menu "Macros" |
---|
108 | Submenu "Simulation Scripting - Beta" |
---|
109 | "Save Configuration",Sim_saveConfProc() |
---|
110 | "Move to Configuration",Sim_moveConfProc() |
---|
111 | "List Configurations",ListSASCALCConfigs() |
---|
112 | "Setup Sim Example",Setup_Sim_Example() |
---|
113 | "1D Count Rates",DryRunProc_1D() |
---|
114 | "2D Dry Run",DryRunProc_2D() |
---|
115 | "Optimal Count Times",OptimalCountProc() |
---|
116 | "Make Table to Combine By Name",MakeCombineTable_byName() |
---|
117 | "Combine by Name",DoCombineFiles_byName(lowQfile,medQfile,hiQfile,saveName) |
---|
118 | "Turn Off Dead Time Correction",Sim_SetDeadTimeTiny() |
---|
119 | End |
---|
120 | End |
---|
121 | |
---|
122 | // run this before the examples to make sure that the proper named configurations exist. |
---|
123 | // this function will overwrite any same-named waves |
---|
124 | Function Setup_Sim_Example() |
---|
125 | |
---|
126 | SetDataFolder root:Packages:NIST:SAS: |
---|
127 | |
---|
128 | Make/O/T/N=20 Config_1m,Config_4m,Config_13m |
---|
129 | Config_1m = {"checkNG7","8","5.08 cm","6","0.115","checkChamber","1/2\"","0","100","25","","","","","","","","","",""} |
---|
130 | Config_4m = {"checkNG7","5","5.08 cm","6","0.115","checkChamber","1/2\"","0","400","0","","","","","","","","","",""} |
---|
131 | Config_13m = {"checkNG7","1","5.08 cm","6","0.115","checkChamber","1/2\"","0","1300","0","","","","","","","","","",""} |
---|
132 | |
---|
133 | SetDataFolder root: |
---|
134 | |
---|
135 | End |
---|
136 | |
---|
137 | Function Example_1DSim() |
---|
138 | |
---|
139 | String confList,ctTimeList,saveNameList,funcStr,titleStr |
---|
140 | |
---|
141 | |
---|
142 | Sim_SetSimulationType(0) //kill the simulation panel |
---|
143 | Sim_SetSimulationType(1) //open the 1D simulation panel |
---|
144 | |
---|
145 | //(1) enter the (unsmeared) function name |
---|
146 | funcStr = "SchulzSpheres_SC" |
---|
147 | Wave cw = $("root:"+getFunctionCoef(funcStr)) |
---|
148 | Sim_SetModelFunction(funcStr) // model function name |
---|
149 | |
---|
150 | //(2) model coefficients here, if needed. Wave name is "cw" |
---|
151 | // then set the sample thickness. Be sure to use an appropriate incoherent background in the model |
---|
152 | Sim_Set1D_Transmission(0.75) // For 1D, I need to supply the transmission |
---|
153 | Sim_SetThickness(0.2) // thickness |
---|
154 | Sim_Set1D_ABS(1) // absolute scaling (1== yes) |
---|
155 | Sim_Set1D_Noise(1) // noise (1== yes, add statistical noise) |
---|
156 | |
---|
157 | cw[0] = 0.1 |
---|
158 | // as needed - look at the parameter list for the model |
---|
159 | |
---|
160 | |
---|
161 | //(3) set the configuration list, times, and saved names |
---|
162 | // -- the mumber of listed configurations must match the number of discrete count times and save names |
---|
163 | // titleStr is the label and is the same for each run of the same sample |
---|
164 | confList = "Config_1m;Config_4m;Config_13m;" |
---|
165 | ctTimeList = "100;300;900;" |
---|
166 | saveNameList = "sim_1m.abs;sim_4m.abs;sim_13m.abs;" |
---|
167 | titleStr = "MySample 1" |
---|
168 | |
---|
169 | // then this runs the samples as listed |
---|
170 | Sim_RunSample_1D(confList,ctTimeList,titleStr,saveNameList) |
---|
171 | |
---|
172 | // no transmissions or empty beam measurements to make for 1D simulation |
---|
173 | |
---|
174 | return(0) |
---|
175 | End |
---|
176 | |
---|
177 | // |
---|
178 | Function Example_2DSim() |
---|
179 | |
---|
180 | String confList,ctTimeList,titleStr,transConfList,transCtTimeList |
---|
181 | Variable runIndex,val,totalTime |
---|
182 | String funcStr |
---|
183 | |
---|
184 | tic() |
---|
185 | |
---|
186 | Sim_SetSimulationType(0) //kill the simulation panel |
---|
187 | Sim_SetSimulationType(2) //open the 2D simulation panel |
---|
188 | Sim_SetSimTimeWarning(36000) //sets the threshold for the warning dialog to 10 hours |
---|
189 | totalTime = 0 |
---|
190 | |
---|
191 | |
---|
192 | //(1) enter the (unsmeared) function name |
---|
193 | funcStr = "SchulzSpheres_SC" |
---|
194 | Wave cw = $("root:"+getFunctionCoef(funcStr)) |
---|
195 | Sim_SetModelFunction(funcStr) // model function name |
---|
196 | |
---|
197 | //(2) set the standard sample cell size (1" diam banjo cell) |
---|
198 | // and set the conditions for beam stop in, and raw counts |
---|
199 | Sim_SetSampleRadius(1.27) // sam radius (cm) |
---|
200 | Sim_SetRawCountsCheck(1) // raw cts? 1== yes |
---|
201 | Sim_SetBeamStopInOut(1) // BS in? 1==yes |
---|
202 | |
---|
203 | //(3) model coefficients here, if needed. Wave name is "cw" |
---|
204 | // then set the sample thickness and incoherent cross section |
---|
205 | |
---|
206 | cw[0] = 0.1 |
---|
207 | // as needed - look at the parameter list for the model |
---|
208 | |
---|
209 | Sim_SetThickness(0.2) // thickness (cm) |
---|
210 | Sim_SetIncohXS(1.3) // incoh XS |
---|
211 | |
---|
212 | //(4) starting run index for the saved raw data files. this will automatically increment |
---|
213 | // as the sample is "Run" |
---|
214 | runIndex = 400 |
---|
215 | |
---|
216 | //(5) set the configuration list, times, a single sample label, and the starting run index |
---|
217 | // -- the mumber of listed configurations must match the number of discrete count times |
---|
218 | confList = "Config_1m;Config_4m;Config_13m;" |
---|
219 | ctTimeList = "100;300;900;" |
---|
220 | transConfList = "Config_13m;" // trans only @ 13m |
---|
221 | transCtTimeList = "1;" // trans count time = 1s |
---|
222 | titleStr = "MySample 1" |
---|
223 | |
---|
224 | // runIndex is PBR and updates as the number of files are written |
---|
225 | |
---|
226 | // this runs the sample |
---|
227 | totalTime += Sim_RunSample_2D(confList,ctTimeList,titleStr,runIndex) |
---|
228 | // this runs the transmissions |
---|
229 | totalTime += Sim_RunTrans_2D(transConfList,transCtTimeList,titleStr,runIndex) |
---|
230 | |
---|
231 | // run the empty beam at all configurations |
---|
232 | // This will automatically change the function to "EC_Empirical" and "empty beam" conditions |
---|
233 | transConfList = "Config_1m;Config_4m;Config_13m;" |
---|
234 | transCtTimeList = "1;1;1;" |
---|
235 | titleStr = "Empty Beam" |
---|
236 | totalTime += Sim_RunEmptyBeamTrans_2D(transConfList,transCtTimeList,titleStr,runIndex) |
---|
237 | |
---|
238 | Print "runIndex = ",runIndex |
---|
239 | |
---|
240 | Sim_SetSimTimeWarning(10) |
---|
241 | |
---|
242 | toc() |
---|
243 | |
---|
244 | return(totalTime) |
---|
245 | End |
---|
246 | |
---|
247 | // pass in a semicolon delimited list of configurations + corresponding count times + saved names |
---|
248 | Function Sim_RunSample_1D(confList,ctTimeList,titleStr,saveNameList) |
---|
249 | String confList,ctTimeList,titleStr,saveNameList |
---|
250 | |
---|
251 | Variable ii,num,ct,cr,numPt |
---|
252 | String twStr,fname,type |
---|
253 | NVAR g_estimateOnly = root:Packages:NIST:SAS:g_estimateOnly // == 1 for just count rate, == 0 (default) to do the simulation and save |
---|
254 | WAVE/Z crWave = root:CR_1D |
---|
255 | WAVE/Z/T fileWave = root:Files_1D |
---|
256 | |
---|
257 | type = "SAS" // since this is a simulation |
---|
258 | num=ItemsInList(confList) |
---|
259 | |
---|
260 | for(ii=0;ii<num;ii+=1) |
---|
261 | twStr = StringFromList(ii, confList,";") |
---|
262 | Wave/T tw=$("root:Packages:NIST:SAS:"+twStr) |
---|
263 | ct = str2num(StringFromList(ii, ctTimeList,";")) |
---|
264 | fname = StringFromList(ii, saveNameList,";") |
---|
265 | |
---|
266 | Sim_MoveToConfiguration(tw) |
---|
267 | Sim_SetCountTime(ct) |
---|
268 | cr = Sim_Do1DSimulation() |
---|
269 | |
---|
270 | // either save it out, or return a table of the count rates |
---|
271 | if(g_estimateOnly) |
---|
272 | numPt = numpnts(crWave) |
---|
273 | InsertPoints numPt, 1, crWave,fileWave |
---|
274 | crWave[numPt] = cr |
---|
275 | fileWave[numPt] = fname |
---|
276 | else |
---|
277 | Sim_Save1D_wName(type,titleStr,fname) //this function will increment the runIndex |
---|
278 | endif |
---|
279 | |
---|
280 | endfor |
---|
281 | |
---|
282 | return(0) |
---|
283 | End |
---|
284 | |
---|
285 | // fakes an empty beam transmission by setting the conditions of the |
---|
286 | // empty cell temporarily to something that doesn't scatter |
---|
287 | Function Sim_RunEmptyBeamTrans_2D(confList,ctTimeList,titleStr,runIndex) |
---|
288 | String confList,ctTimeList,titleStr |
---|
289 | Variable &runIndex |
---|
290 | |
---|
291 | Wave cw = root:Packages:NIST:SAS:coef_ECEmp //EC coefs are in the SAS folder, not root: |
---|
292 | Variable totalTime |
---|
293 | |
---|
294 | // change the function and coefficients |
---|
295 | Sim_SetModelFunction("EC_Empirical") |
---|
296 | cw = {1e-18,3.346,0,9,0} |
---|
297 | Sim_SetIncohXS(0) // incoh XS = 0 for empty beam |
---|
298 | Sim_SetThickness(0.1) // thickness (cm) to give proper level of scattering |
---|
299 | |
---|
300 | |
---|
301 | totalTime = Sim_RunTrans_2D(confList,ctTimeList,titleStr,runIndex) |
---|
302 | |
---|
303 | // change them back |
---|
304 | cw = {2.2e-08,3.346,0.0065,9,0.016} |
---|
305 | |
---|
306 | return(totalTime) |
---|
307 | End |
---|
308 | |
---|
309 | |
---|
310 | // should be called with each list having only one item |
---|
311 | // and a count time of 1 s |
---|
312 | // |
---|
313 | // -- for an empty beam, before calling, set the incoh XS = 0 and set the scale |
---|
314 | // of the model to something tiny so that there is no coherent scattering |
---|
315 | // |
---|
316 | Function Sim_RunTrans_2D(confList,ctTimeList,titleStr,runIndex) |
---|
317 | String confList,ctTimeList,titleStr |
---|
318 | Variable &runIndex |
---|
319 | |
---|
320 | Variable ii,num,ct,index,totalTime |
---|
321 | String twStr,type |
---|
322 | |
---|
323 | NVAR g_estimateOnly = root:Packages:NIST:SAS:g_estimateOnly // == 1 for just a time estimate, == 0 (default) to do the simulation |
---|
324 | NVAR g_estimatedMCTime = root:Packages:NIST:SAS:g_estimatedMCTime // estimated MC sim time |
---|
325 | totalTime = 0 |
---|
326 | |
---|
327 | type = "SAS" // since this is a simulation |
---|
328 | num=ItemsInList(confList) |
---|
329 | |
---|
330 | for(ii=0;ii<num;ii+=1) |
---|
331 | twStr = StringFromList(ii, confList,";") |
---|
332 | Wave/T tw=$("root:Packages:NIST:SAS:"+twStr) |
---|
333 | ct = str2num(StringFromList(ii, ctTimeList,";")) |
---|
334 | |
---|
335 | Sim_MoveToConfiguration(tw) |
---|
336 | Sim_SetBeamStopInOut(0) // BS out for Trans |
---|
337 | Sim_SetCountTime(ct) |
---|
338 | Sim_DoMCSimulation() |
---|
339 | |
---|
340 | if(g_estimateOnly) |
---|
341 | totalTime += g_estimatedMCTime // don't save, don't increment. time passed back as global after each MC simulation |
---|
342 | else |
---|
343 | SaveAsVAXButtonProc("",runIndex=runIndex,simLabel=(titleStr+" at "+twStr)) |
---|
344 | runIndex += 1 |
---|
345 | endif |
---|
346 | |
---|
347 | endfor |
---|
348 | |
---|
349 | Sim_SetBeamStopInOut(1) // put the BS back in |
---|
350 | |
---|
351 | return(totalTime) |
---|
352 | End |
---|
353 | |
---|
354 | |
---|
355 | |
---|
356 | // if just an estimate, I can also get the count rate too |
---|
357 | // WAVE results = root:Packages:NIST:SAS:results |
---|
358 | // Print "Sample Simulation (2D) CR = ",results[9]/ctTime |
---|
359 | // -- for estimates, iMon is set to 1000, so time=1000/(root:Packages:NIST:SAS:gImon) |
---|
360 | Function Sim_RunSample_2D(confList,ctTimeList,titleStr,runIndex) |
---|
361 | String confList,ctTimeList,titleStr |
---|
362 | Variable &runIndex |
---|
363 | |
---|
364 | Variable ii,num,ct,index,totalTime |
---|
365 | String twStr,type |
---|
366 | |
---|
367 | NVAR g_estimateOnly = root:Packages:NIST:SAS:g_estimateOnly // == 1 for just a time estimate, == 0 (default) to do the simulation |
---|
368 | NVAR g_estimatedMCTime = root:Packages:NIST:SAS:g_estimatedMCTime // estimated MC sim time |
---|
369 | totalTime = 0 |
---|
370 | |
---|
371 | type = "SAS" // since this is a simulation |
---|
372 | num=ItemsInList(confList) |
---|
373 | |
---|
374 | |
---|
375 | for(ii=0;ii<num;ii+=1) |
---|
376 | twStr = StringFromList(ii, confList,";") |
---|
377 | Wave/T tw=$("root:Packages:NIST:SAS:"+twStr) |
---|
378 | ct = str2num(StringFromList(ii, ctTimeList,";")) |
---|
379 | |
---|
380 | Sim_MoveToConfiguration(tw) |
---|
381 | Sim_SetBeamStopInOut(1) // BS in? |
---|
382 | Sim_SetCountTime(ct) |
---|
383 | Sim_DoMCSimulation() |
---|
384 | |
---|
385 | if(g_estimateOnly) |
---|
386 | totalTime += g_estimatedMCTime // don't save, don't increment. time passed back as global after each MC simulation |
---|
387 | else |
---|
388 | SaveAsVAXButtonProc("",runIndex=runIndex,simLabel=(titleStr+" at "+twStr)) |
---|
389 | runIndex += 1 |
---|
390 | endif |
---|
391 | |
---|
392 | endfor |
---|
393 | |
---|
394 | return(totalTime) |
---|
395 | End |
---|
396 | |
---|
397 | // a prototype function with no parameters |
---|
398 | // for a real experiment - it must return the total time, if you want a proper estimate |
---|
399 | Function Sim_Expt_Proto() |
---|
400 | Print "In the Sim_Expt_Proto -- error" |
---|
401 | return(0) |
---|
402 | End |
---|
403 | |
---|
404 | Proc DryRunProc_2D(funcStr) |
---|
405 | String funcStr |
---|
406 | Sim_2DDryRun(funcStr) |
---|
407 | end |
---|
408 | |
---|
409 | // pass the function string, no parameters |
---|
410 | Function Sim_2DDryRun(funcStr) |
---|
411 | String funcStr |
---|
412 | |
---|
413 | FUNCREF Sim_Expt_Proto func=$funcStr |
---|
414 | |
---|
415 | NVAR g_estimateOnly = root:Packages:NIST:SAS:g_estimateOnly |
---|
416 | g_estimateOnly = 1 |
---|
417 | |
---|
418 | Variable totalTime |
---|
419 | // totalTime = Sim_CountTime_2D() // your "exeriment" here, returning the totalTime |
---|
420 | |
---|
421 | totalTime = func() |
---|
422 | g_estimateOnly = 0 |
---|
423 | |
---|
424 | Printf "Total Estimated Time = %g s or %g h\r",totalTime,totalTime/3600 |
---|
425 | end |
---|
426 | |
---|
427 | Proc DryRunProc_1D(funcStr) |
---|
428 | String funcStr |
---|
429 | Sim_1DDryRun(funcStr) |
---|
430 | end |
---|
431 | |
---|
432 | // pass the function string, no parameters |
---|
433 | // makes a (new) table of the files and CR |
---|
434 | Function Sim_1DDryRun(funcStr) |
---|
435 | String funcStr |
---|
436 | |
---|
437 | FUNCREF Sim_Expt_Proto func=$funcStr |
---|
438 | |
---|
439 | NVAR g_estimateOnly = root:Packages:NIST:SAS:g_estimateOnly |
---|
440 | g_estimateOnly = 1 |
---|
441 | |
---|
442 | Variable totalTime |
---|
443 | |
---|
444 | Make/O/D/N=0 root:CR_1D |
---|
445 | Make/O/T/N=0 root:Files_1D |
---|
446 | |
---|
447 | totalTime = func() |
---|
448 | g_estimateOnly = 0 |
---|
449 | |
---|
450 | Edit Files_1D,CR_1D |
---|
451 | |
---|
452 | // Printf "Total Estimated Time = %g s or %g h\r",totalTime,totalTime/3600 |
---|
453 | return(0) |
---|
454 | end |
---|
455 | |
---|
456 | |
---|
457 | |
---|
458 | |
---|
459 | |
---|
460 | Proc OptimalCountProc(samCountRate,emptyCountRate) |
---|
461 | Variable samCountRate,emptyCountRate |
---|
462 | OptimalCount(samCountRate,emptyCountRate) |
---|
463 | End |
---|
464 | |
---|
465 | Function OptimalCount(samCR,empCR) |
---|
466 | Variable samCR,empCR |
---|
467 | |
---|
468 | String str |
---|
469 | Variable ratio,target |
---|
470 | ratio = sqrt(samCR/empCR) |
---|
471 | |
---|
472 | str = "For %g Sample counts, t sam = %g s and t emp = %g s\r" |
---|
473 | |
---|
474 | target = 1e6 |
---|
475 | printf str,target,round(target/samCR),round((target/samCR)/ratio) |
---|
476 | |
---|
477 | target = 1e5 |
---|
478 | printf str,target,round(target/samCR),round((target/samCR)/ratio) |
---|
479 | |
---|
480 | target = 1e4 |
---|
481 | printf str,target,round(target/samCR),round((target/samCR)/ratio) |
---|
482 | return(0) |
---|
483 | end |
---|
484 | |
---|
485 | |
---|
486 | // |
---|
487 | // Important - in the reduction process, set the dead time correction to something |
---|
488 | // really small, say 10^-15 so that it won't have any effect (since the detector CR is fictionally high) |
---|
489 | // |
---|
490 | Function Sim_SetDeadTimeTiny() |
---|
491 | |
---|
492 | // NVAR DeadtimeNG3_ILL = root:myGlobals:DeadtimeNG3_ILL //pixel resolution in cm |
---|
493 | // NVAR DeadtimeNG5_ILL = root:myGlobals:DeadtimeNG5_ILL |
---|
494 | // NVAR DeadtimeNG7_ILL = root:myGlobals:DeadtimeNG7_ILL |
---|
495 | // NVAR DeadtimeNGB_ILL = root:myGlobals:DeadtimeNGB_ILL |
---|
496 | NVAR DeadtimeNG3_ORNL_VAX = root:myGlobals:DeadtimeNG3_ORNL_VAX |
---|
497 | // NVAR DeadtimeNG3_ORNL_ICE = root:myGlobals:DeadtimeNG3_ORNL_ICE |
---|
498 | // NVAR DeadtimeNG5_ORNL = root:myGlobals:DeadtimeNG5_ORNL |
---|
499 | NVAR DeadtimeNG7_ORNL_VAX = root:myGlobals:DeadtimeNG7_ORNL_VAX |
---|
500 | // NVAR DeadtimeNG7_ORNL_ICE = root:myGlobals:DeadtimeNG7_ORNL_ICE |
---|
501 | NVAR DeadtimeNGB_ORNL_ICE = root:myGlobals:DeadtimeNGB_ORNL_ICE |
---|
502 | NVAR DeadtimeDefault = root:myGlobals:DeadtimeDefault |
---|
503 | |
---|
504 | DeadtimeNG3_ORNL_VAX = 1e-15 |
---|
505 | DeadtimeNG7_ORNL_VAX = 1e-15 |
---|
506 | DeadtimeNGB_ORNL_ICE = 1e-15 |
---|
507 | DeadtimeDefault = 1e-15 |
---|
508 | |
---|
509 | return(0) |
---|
510 | End |
---|
511 | |
---|
512 | |
---|
513 | |
---|
514 | ///////////////////////////////////////////////////////////////////// |
---|
515 | ///////////// All of the utility functions to make things "move" |
---|
516 | |
---|
517 | |
---|
518 | |
---|
519 | // set the wavelength |
---|
520 | Function Sim_SetLambda(val) |
---|
521 | Variable val |
---|
522 | |
---|
523 | NVAR lam = root:Packages:NIST:SAS:gLambda |
---|
524 | lam=val |
---|
525 | LambdaSetVarProc("",val,num2str(val),"") |
---|
526 | return(0) |
---|
527 | end |
---|
528 | |
---|
529 | // set the wavelength spread |
---|
530 | // ?? what are the allowable choices |
---|
531 | // there are 3 choices for each instrument |
---|
532 | // |
---|
533 | // TO DO ?? do this in a better way |
---|
534 | // currently there is no error checking... |
---|
535 | // |
---|
536 | Function Sim_SetDeltaLambda(strVal) |
---|
537 | String strVal |
---|
538 | |
---|
539 | |
---|
540 | DeltaLambdaPopMenuProc("",1,strVal) // recalculates intensity if 2nd param==1, skip if == 0 |
---|
541 | PopupMenu popup0_2 win=SASCALC,popmatch=strVal |
---|
542 | // ControlUpdate/W=SASCALC popup0_2 |
---|
543 | |
---|
544 | return(0) |
---|
545 | End |
---|
546 | |
---|
547 | // if state == 0, lenses out (box un-checked, no parameters change) |
---|
548 | // if state == 1, lenses in, changes guides, aperture, SDD and wavelength appropriately |
---|
549 | // if prisms desired, follow this call with a set wavelength=17.2 |
---|
550 | Function Sim_SetLenses(state) |
---|
551 | Variable state |
---|
552 | |
---|
553 | LensCheckProc("",state) |
---|
554 | CheckBox checkLens,win=SASCALC,value=state |
---|
555 | |
---|
556 | return(0) |
---|
557 | End |
---|
558 | |
---|
559 | // instrName = "checkNG3" or "checkNG7" or "checkNGB" |
---|
560 | // these are the only allowable choices |
---|
561 | Function Sim_SetInstrument(instrName) |
---|
562 | String instrName |
---|
563 | |
---|
564 | SelectInstrumentCheckProc(instrName,0) |
---|
565 | return(0) |
---|
566 | End |
---|
567 | |
---|
568 | |
---|
569 | //two steps to change the number of guides |
---|
570 | // - first the number of guides, then the source aperture (if 0g, 7g where there are choices) |
---|
571 | // |
---|
572 | // strVal is "5 cm" or "1.43 cm" (MUST be identical to the popup string, MUST have the units) |
---|
573 | /// |
---|
574 | Function Sim_SetNumGuides_SrcAp(ng,strVal) |
---|
575 | Variable ng |
---|
576 | String strVal |
---|
577 | |
---|
578 | NVAR gNg=root:Packages:NIST:SAS:gNg |
---|
579 | gNg = ng |
---|
580 | |
---|
581 | Slider SC_Slider,win=SASCALC,variable=root:Packages:NIST:SAS:gNg //guides |
---|
582 | |
---|
583 | // with the new number of guides, update the allowable source aperture popups |
---|
584 | DoWindow/F SASCALC |
---|
585 | UpdateControls() |
---|
586 | |
---|
587 | // TO DO -- this needs some logic added, or an additional parameter to properly set the |
---|
588 | // source aperture |
---|
589 | |
---|
590 | popupmenu popup0 win=SASCALC,popmatch=strVal |
---|
591 | Variable dum=sourceApertureDiam() //sets the proper value in the header wave |
---|
592 | return(0) |
---|
593 | End |
---|
594 | |
---|
595 | // strVal is "1/2\"" or similar. note the extra backslash so that " is part of the string |
---|
596 | // |
---|
597 | Function Sim_SetSampleApertureDiam(strVal) |
---|
598 | String strVal |
---|
599 | |
---|
600 | popupmenu popup0_1 win=SASCALC,popmatch=strVal |
---|
601 | Variable dum=sampleApertureDiam() //sets the proper value in the header wave |
---|
602 | return(0) |
---|
603 | End |
---|
604 | |
---|
605 | Function Sim_SetOffset(offset) |
---|
606 | Variable offset |
---|
607 | |
---|
608 | NVAR detOffset = root:Packages:NIST:SAS:gOffset |
---|
609 | detOffset = offset //in cm |
---|
610 | detectorOffset() //changes header and estimates (x,y) beamcenter |
---|
611 | return(0) |
---|
612 | end |
---|
613 | |
---|
614 | Function Sim_SetSDD(sdd) |
---|
615 | Variable sdd |
---|
616 | |
---|
617 | NVAR detDist = root:Packages:NIST:SAS:gDetDist |
---|
618 | |
---|
619 | detDist = sdd |
---|
620 | sampleToDetectorDist() //changes the SDD and wave (DetDist is the global) |
---|
621 | return(0) |
---|
622 | end |
---|
623 | |
---|
624 | |
---|
625 | // change the huber/sample chamber position |
---|
626 | // if str="checkHuber", the pos is set to huber |
---|
627 | // otherwise, it's set to the sample chamber position |
---|
628 | // |
---|
629 | Function Sim_SetTablePos(strVal) |
---|
630 | String strVal |
---|
631 | |
---|
632 | TableCheckProc(strVal,0) |
---|
633 | return(0) |
---|
634 | end |
---|
635 | |
---|
636 | |
---|
637 | // |
---|
638 | // ------------ specifc for the simulation |
---|
639 | // |
---|
640 | // |
---|
641 | // type = 0 = none, kills panel |
---|
642 | // type = 1 = 1D |
---|
643 | // type = 2 = 2D |
---|
644 | // |
---|
645 | // -- DON'T leave the do2D global set to 1 - be sure to set back to 0 before exiting |
---|
646 | // |
---|
647 | Function Sim_SetSimulationType(type) |
---|
648 | Variable type |
---|
649 | |
---|
650 | STRUCT WMCheckboxAction CB_Struct |
---|
651 | Variable checkState |
---|
652 | if(type == 1 || type == 2) |
---|
653 | CB_Struct.checked = 1 |
---|
654 | checkState = 1 |
---|
655 | else |
---|
656 | CB_Struct.checked = 0 |
---|
657 | checkState = 0 |
---|
658 | endif |
---|
659 | |
---|
660 | NVAR do2D = root:Packages:NIST:SAS:gDoMonteCarlo |
---|
661 | |
---|
662 | if(type == 1) |
---|
663 | do2D = 0 |
---|
664 | else |
---|
665 | do2D = 1 |
---|
666 | endif |
---|
667 | |
---|
668 | SimCheckProc(CB_Struct) |
---|
669 | |
---|
670 | // Very important |
---|
671 | do2D = 0 |
---|
672 | |
---|
673 | CheckBox checkSim win=SASCALC,value=checkState |
---|
674 | return(0) |
---|
675 | End |
---|
676 | |
---|
677 | Function Sim_DoMCSimulation() |
---|
678 | |
---|
679 | STRUCT WMButtonAction ba |
---|
680 | ba.eventCode = 2 //fake mouse click on button |
---|
681 | |
---|
682 | MC_DoItButtonProc(ba) |
---|
683 | return(0) |
---|
684 | End |
---|
685 | |
---|
686 | Function Sim_Do1DSimulation() |
---|
687 | |
---|
688 | ReCalculateInten(1) |
---|
689 | NVAR estCR = root:Packages:NIST:SAS:g_1DEstDetCR |
---|
690 | return(estCR) |
---|
691 | End |
---|
692 | |
---|
693 | // counting time (set this last - after all of the instrument moves are done AND the |
---|
694 | // intensity has been updated) |
---|
695 | // |
---|
696 | // ctTime is in seconds |
---|
697 | // sets the global variable, and fakes an "entry" in that field |
---|
698 | Function Sim_SetCountTime(ctTime) |
---|
699 | Variable ctTime |
---|
700 | |
---|
701 | STRUCT WMSetVariableAction sva |
---|
702 | NVAR ct = root:Packages:NIST:SAS:gCntTime |
---|
703 | ct=ctTime |
---|
704 | sva.dval = ctTime //seconds |
---|
705 | sva.eventCode = 3 //live update code |
---|
706 | CountTimeSetVarProc(sva) |
---|
707 | return(0) |
---|
708 | End |
---|
709 | |
---|
710 | |
---|
711 | Function Sim_SetIncohXS(val) |
---|
712 | Variable val |
---|
713 | |
---|
714 | NVAR xs = root:Packages:NIST:SAS:gSig_incoh |
---|
715 | xs = val |
---|
716 | return(0) |
---|
717 | End |
---|
718 | |
---|
719 | Function Sim_SetThickness(val) |
---|
720 | Variable val |
---|
721 | |
---|
722 | NVAR th = root:Packages:NIST:SAS:gThick |
---|
723 | th = val |
---|
724 | return(0) |
---|
725 | End |
---|
726 | |
---|
727 | Function Sim_SetSampleRadius(val) |
---|
728 | Variable val |
---|
729 | |
---|
730 | NVAR r2 = root:Packages:NIST:SAS:gR2 |
---|
731 | r2 = val |
---|
732 | |
---|
733 | return(0) |
---|
734 | End |
---|
735 | |
---|
736 | Function Sim_SetNumberOfNeutrons(val) |
---|
737 | Variable val |
---|
738 | |
---|
739 | NVAR num = root:Packages:NIST:SAS:gImon |
---|
740 | num = val |
---|
741 | |
---|
742 | return(0) |
---|
743 | End |
---|
744 | |
---|
745 | // 1 == beam stop in |
---|
746 | // 0 == beam stop out == transmission |
---|
747 | // |
---|
748 | Function Sim_SetBeamStopInOut(val) |
---|
749 | Variable val |
---|
750 | |
---|
751 | NVAR BS = root:Packages:NIST:SAS:gBeamStopIn //set to zero for beamstop out (transmission) |
---|
752 | WAVE rw=root:Packages:NIST:SAS:realsRead |
---|
753 | |
---|
754 | BS = val //set the global |
---|
755 | |
---|
756 | // fake the header |
---|
757 | if(BS == 1) |
---|
758 | rw[37] = 0 // make sure BS X = 0 if BS is in |
---|
759 | else |
---|
760 | rw[37] = -10 // fake BS out as X = -10 cm |
---|
761 | endif |
---|
762 | |
---|
763 | return(0) |
---|
764 | End |
---|
765 | |
---|
766 | Function Sim_SetRawCountsCheck(val) |
---|
767 | Variable val |
---|
768 | |
---|
769 | NVAR rawCt = root:Packages:NIST:SAS:gRawCounts |
---|
770 | rawCt = val |
---|
771 | return(0) |
---|
772 | End |
---|
773 | |
---|
774 | Function Sim_Set1D_ABS(val) |
---|
775 | Variable val |
---|
776 | |
---|
777 | NVAR gAbs = root:Packages:NIST:SAS:g_1D_DoABS |
---|
778 | gAbs = val |
---|
779 | |
---|
780 | return(0) |
---|
781 | End |
---|
782 | |
---|
783 | Function Sim_Set1D_Noise(val) |
---|
784 | Variable val |
---|
785 | |
---|
786 | NVAR doNoise = root:Packages:NIST:SAS:g_1D_AddNoise |
---|
787 | doNoise = val |
---|
788 | return(0) |
---|
789 | End |
---|
790 | |
---|
791 | Function Sim_Set1D_Transmission(val) |
---|
792 | Variable val |
---|
793 | |
---|
794 | NVAR trans = root:Packages:NIST:SAS:gSamTrans |
---|
795 | trans = val |
---|
796 | return(0) |
---|
797 | End |
---|
798 | |
---|
799 | Function Sim_SetModelFunction(strVal) |
---|
800 | String strVal |
---|
801 | |
---|
802 | DoWindow MC_SASCALC |
---|
803 | if(V_flag==1) |
---|
804 | //then 2D |
---|
805 | PopupMenu MC_popup0 win=MC_SASCALC,popmatch=strVal |
---|
806 | endif |
---|
807 | |
---|
808 | DoWindow Sim_1D_Panel |
---|
809 | if(V_flag==1) |
---|
810 | //then 1D |
---|
811 | PopupMenu MC_popup0 win=Sim_1D_Panel,popmatch=strVal |
---|
812 | endif |
---|
813 | |
---|
814 | SVAR gStr = root:Packages:NIST:SAS:gFuncStr |
---|
815 | gStr = strVal |
---|
816 | |
---|
817 | return(0) |
---|
818 | End |
---|
819 | |
---|
820 | |
---|
821 | // ------------ |
---|
822 | |
---|
823 | // |
---|
824 | // set the threshold for the time warning dialog to some really large value (say 36000 s) |
---|
825 | // while doing the simulation to keep the dialog from popping up and stopping the simulation. |
---|
826 | // then be sure to set it back to 10 s for "normal" simulations that are atttended |
---|
827 | // |
---|
828 | // input val is in seconds |
---|
829 | Function Sim_SetSimTimeWarning(val) |
---|
830 | Variable val |
---|
831 | |
---|
832 | NVAR SimTimeWarn = root:Packages:NIST:SAS:g_SimTimeWarn |
---|
833 | SimTimeWarn = val //sets the threshold for the warning dialog |
---|
834 | |
---|
835 | return(0) |
---|
836 | end |
---|
837 | |
---|
838 | // if you need to eliminate the high count data to save the rest of the set |
---|
839 | Function Sim_TrimOverflowCounts() |
---|
840 | Wave w = root:Packages:NIST:SAS:linear_data |
---|
841 | w = (w > 2767000) ? 0 : w |
---|
842 | return(0) |
---|
843 | End |
---|
844 | |
---|
845 | // if home path exists, save there, otherwise present a dialog |
---|
846 | // (no sense to use catPathName, since this is simulation, not real data |
---|
847 | // |
---|
848 | Function Sim_Save1D_wName(type,titleStr,fname) |
---|
849 | String type,titleStr,fname |
---|
850 | |
---|
851 | String fullPath |
---|
852 | NVAR autoSaveIndex = root:Packages:NIST:SAS:gAutoSaveIndex |
---|
853 | |
---|
854 | //now save the data |
---|
855 | PathInfo home |
---|
856 | fullPath = S_path + fname |
---|
857 | |
---|
858 | Save_1DSimData("",runIndex=autoSaveIndex,simLabel=titleStr,saveName=fullPath) |
---|
859 | |
---|
860 | autoSaveIndex += 1 |
---|
861 | return(0) |
---|
862 | End |
---|
863 | |
---|
864 | Proc Sim_saveConfProc(waveStr) |
---|
865 | String waveStr |
---|
866 | |
---|
867 | Sim_SaveConfiguration(waveStr) |
---|
868 | End |
---|
869 | // |
---|
870 | // just make a wave and fill it |
---|
871 | // I'll keep track of what's in each element |
---|
872 | // -- not very user friendly, but nobody needs to see this |
---|
873 | // |
---|
874 | // poll the panel to fill it in |
---|
875 | // |
---|
876 | // 0 = instrument |
---|
877 | // 1 = number of guides |
---|
878 | // 2 = source aperture |
---|
879 | // 3 = lambda |
---|
880 | // 4 = delta lambda |
---|
881 | // 5 = huber/chamber |
---|
882 | // 6 = sample aperture |
---|
883 | // 7 = lenses/prism/none |
---|
884 | // 8 = SDD |
---|
885 | // 9 = offset |
---|
886 | // |
---|
887 | Function Sim_SaveConfiguration(waveStr) |
---|
888 | String waveStr |
---|
889 | |
---|
890 | String str="" |
---|
891 | |
---|
892 | SetDataFolder root:Packages:NIST:SAS |
---|
893 | |
---|
894 | Make/O/T/N=20 $("Config_"+waveStr) |
---|
895 | Wave/T tw=$("Config_"+waveStr) |
---|
896 | tw = "" |
---|
897 | |
---|
898 | // 0 = instrument |
---|
899 | SVAR instStr = root:Packages:NIST:SAS:gInstStr |
---|
900 | tw[0] = "check"+instStr |
---|
901 | |
---|
902 | // 1 = number of guides |
---|
903 | NVAR ng = root:Packages:NIST:SAS:gNg |
---|
904 | tw[1] = num2str(ng) |
---|
905 | |
---|
906 | // 2 = source aperture |
---|
907 | ControlInfo/W=SASCALC popup0 |
---|
908 | tw[2] = S_Value |
---|
909 | |
---|
910 | // 3 = lambda |
---|
911 | NVAR lam = root:Packages:NIST:SAS:gLambda |
---|
912 | tw[3] = num2str(lam) |
---|
913 | |
---|
914 | // 4 = delta lambda |
---|
915 | // NVAR dlam = root:Packages:NIST:SAS:gDeltaLambda |
---|
916 | // tw[4] = num2str(dlam) |
---|
917 | |
---|
918 | //or |
---|
919 | ControlInfo/W=SASCALC popup0_2 |
---|
920 | tw[4] = S_Value |
---|
921 | |
---|
922 | |
---|
923 | // 5 = huber/chamber |
---|
924 | NVAR sampleTable = root:Packages:NIST:SAS:gTable //2=chamber, 1=table |
---|
925 | if(sampleTable==1) |
---|
926 | str = "checkHuber" |
---|
927 | else |
---|
928 | str = "checkChamber" |
---|
929 | endif |
---|
930 | tw[5] = str |
---|
931 | |
---|
932 | // 6 = sample aperture |
---|
933 | ControlInfo/W=SASCALC popup0_1 |
---|
934 | tw[6] = S_Value |
---|
935 | |
---|
936 | // 7 = lenses/prism/none |
---|
937 | NVAR lens = root:Packages:NIST:SAS:gUsingLenses //==0 for no lenses, 1 for lenses(or prisms) |
---|
938 | tw[7] = num2str(lens) |
---|
939 | |
---|
940 | // 8 = SDD |
---|
941 | NVAR sdd = root:Packages:NIST:SAS:gDetDist |
---|
942 | tw[8] = num2str(sdd) |
---|
943 | |
---|
944 | // 9 = offset |
---|
945 | NVAR offset = root:Packages:NIST:SAS:gOffset |
---|
946 | tw[9] = num2str(offset) |
---|
947 | |
---|
948 | // |
---|
949 | |
---|
950 | SetDataFolder root: |
---|
951 | return(0) |
---|
952 | End |
---|
953 | |
---|
954 | Proc Sim_moveConfProc(waveStr) |
---|
955 | String waveStr |
---|
956 | Prompt waveStr,"Select Configuration",popup,ListSASCALCConfigs() |
---|
957 | |
---|
958 | Sim_MoveToConfiguration($("root:Packages:NIST:SAS:"+waveStr)) |
---|
959 | End |
---|
960 | // restore the configuration given a wave of information |
---|
961 | // |
---|
962 | // be sure to recalculate the intensity after all is set |
---|
963 | // -- some changes recalculate, some do not... |
---|
964 | // |
---|
965 | Function Sim_MoveToConfiguration(tw) |
---|
966 | WAVE/T tw |
---|
967 | |
---|
968 | |
---|
969 | // 0 = instrument |
---|
970 | Sim_SetInstrument(tw[0]) |
---|
971 | |
---|
972 | // 1 = number of guides |
---|
973 | // 2 = source aperture |
---|
974 | Sim_SetNumGuides_SrcAp(str2num(tw[1]),tw[2]) |
---|
975 | |
---|
976 | // 3 = lambda |
---|
977 | Sim_SetLambda(str2num(tw[3])) |
---|
978 | |
---|
979 | // 4 = delta lambda |
---|
980 | Sim_SetDeltaLambda(tw[4]) |
---|
981 | |
---|
982 | // 5 = huber/chamber |
---|
983 | Sim_SetTablePos(tw[5]) |
---|
984 | |
---|
985 | // 6 = sample aperture |
---|
986 | Sim_SetSampleApertureDiam(tw[6]) |
---|
987 | |
---|
988 | // 7 = lenses/prism/none |
---|
989 | Sim_SetLenses(str2num(tw[7])) |
---|
990 | |
---|
991 | // 8 = SDD |
---|
992 | Sim_SetSDD(str2num(tw[8])) |
---|
993 | |
---|
994 | // 9 = offset |
---|
995 | Sim_SetOffset(str2num(tw[9])) |
---|
996 | |
---|
997 | |
---|
998 | ReCalculateInten(1) |
---|
999 | return(0) |
---|
1000 | end |
---|
1001 | |
---|
1002 | |
---|
1003 | ///////////// a panel to (maybe) write to speed the setup of the runs |
---|
1004 | // |
---|
1005 | Function/S ListSASCALCConfigs() |
---|
1006 | String str |
---|
1007 | SetDataFolder root:Packages:NIST:SAS |
---|
1008 | str = WaveList("Conf*",";","") |
---|
1009 | SetDataFolder root: |
---|
1010 | print str |
---|
1011 | return(str) |
---|
1012 | End |
---|
1013 | |
---|
1014 | //Proc Sim_SetupRunPanel() : Panel |
---|
1015 | // PauseUpdate; Silent 1 // building window... |
---|
1016 | // NewPanel /W=(399,44,764,386) |
---|
1017 | // ModifyPanel cbRGB=(56639,28443,117) |
---|
1018 | // ShowTools/A |
---|
1019 | //EndMacro |
---|