source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/SASCALC.ipf @ 889

Last change on this file since 889 was 889, checked in by srkline, 10 years ago

Added the attenuator table and flux values for the 10m SANS instrument as measured by John Barker. Other changes to the code for the 10m SANS appear to be complete, pending some more thorough testing.

File size: 73.0 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=1.0
3#pragma IgorVersion=6.1
4#pragma ModuleName=SASCALC
5
6// SASCALC.ipf
7//
8// 04 OCT 2006 SRK
9// 30 OCT 2006 SRK - corrected beamDiameter size in attenuator calculation (Bh vs Bm)
10// 11 DEC 2006 SRK - added 2.5 cm A1 option for NG3@7guide config
11// 09 MAR 2007 SRK - now appends text of each frozen configuration for printing
12//                                        - colorized frozen traces so that they aren't all red (unfrozen is black)
13// 19 MAR 2007 SRK - corrections added for projected BS diameter at anode plane
14// 11 APR 2007 SRK - default aperture offset of 5 cm added to match VAX implementation
15// nn AUG 2007 SRK - added defulat sample aperture size
16//                                               added option of lenses, approximated beamDiam=sourceDiam, BSdiam=1"
17//                                               Lens flux, trans is not corrected for lens/prism transmission
18//                                               Lenses can still be inserted in incorrect cases, and are not automatically taken out
19// 27 JAN 2009 SRK - Changed behavior of Lens checkbox. Now, it SETS parameters as needed for proper
20//                                               configuration. 17.2 can be typed in for lens/prism on NG3. Invalid conditions
21//                                               will automatically uncheck the box
22// 03 MAR 2012 SRK - Added new source apertures in 6th and 7th boxes of NG3
23//
24// 05 OCT 2012 SRK - (not visible) but added the skeleton bits for the 10m SANS instrument. Don't have the
25//                                                      details of the distances, etc, but I'll fill that in as needed
26//                                              -- to "un-hide" the 10m SANS, uncomment the CheckBox control in the panel (see the constant declared below)
27// 03 JAN 2013 SRK -- settled on "A" for new 10m SANS and "B" for the NG3 when it's relocated. Both instruments share
28//                                                      NGB, so this will have to do. files will be SA4 and SA5 respectively, if the VAX naming continues
29//
30//
31//
32// calculate what q-values you get based on the instruments settings
33// that you would typically input to SASCALC
34// calculation is for (80A radius spheres) * (beam stop shadow factor)
35// or a Debye function (Rg=50A) * (beam stop shadow factor)
36// - NOT true intensity, not counts, just a display
37//
38// TODO_10m:
39//
40// -- For the 10m SANS...
41//
42//              x- how many guides are there
43//              x- no lenses? focusing pinholes?
44//              x- aperture sizes?
45//              - flux values
46//              x- huber/sample chamber is inline, so get rid of this for 10m (gray out?)
47//              x- does this hook into anywhere in the main program? Attenuators, etc.
48//                      where knowledge of the 10m SANS is necessary??
49//              x- setting the instrument "number" is done here as "10". This will have a trickle-down effect for the places that use
50//              the global -- root:Packages:NIST:SAS:instrument (search for it everywhere...)
51//              x- repair the naming/numbering scheme to look for the string "NGx" and switch on that, not a number, which is unreliable and confusing.
52//
53// use str2hex(str) (my function) to convert "A" to 10
54//
55// Optional:
56// - freeze configurations with a user defined tag
57// - different model functions (+ change simple parameters)
58// - resolution smeared models
59// - "simulation" of data and error bars given a model and a total number of detector counts
60// - streamline code (globals needed in panel vs. wave needed for calculation)
61//
62// - there is a lot of re-calculation of things (a consequence of the fake-OO) that could be streamlined
63//
64// Done:
65// - include resolution effects (includes BS effect, smeared model)
66// - (data = 1) then multiply by a typical form factor
67// - masked two pixels around the edge, as default
68// - conversion from # guides to SSD from sascalc
69// - show multiple configurations at once
70// - interactive graphics on panel
71// - full capabilities of SASCALC
72// - correct beamstop diameter
73// - get the sample/huber position properly incorporated (ssd and sdd)
74// - get SDD value to update when switching NG7->NG3 and illegal value
75// - disallow 6 guides at NG3 (post a warning)
76//
77//
78
79Constant show10mSANS = 1
80
81
82
83Proc SASCALC()
84        DoWindow/F SASCALC
85        if(V_flag==0)
86                S_initialize_space()
87                initNG3()               //start life as NG3
88                Sascalc_Panel()
89                ReCalculateInten(1)             //will use defaults
90        Endif
91
92End
93
94Proc S_initialize_space()
95        NewDataFolder/O root:Packages
96        NewDataFolder/O root:Packages:NIST
97        NewDataFolder/O root:Packages:NIST:SAS
98       
99        Make/O/D/N=23 root:Packages:NIST:SAS:integersRead
100        Make/O/D/N=52 root:Packages:NIST:SAS:realsRead
101        Make/O/T/N=11 root:Packages:NIST:SAS:textRead
102        // data
103        Make/O/D/N=(128,128) root:Packages:NIST:SAS:data,root:Packages:NIST:SAS:linear_data
104        Make/O/D/N=2 root:Packages:NIST:SAS:aveint,root:Packages:NIST:SAS:qval,root:Packages:NIST:SAS:sigave
105        root:Packages:NIST:SAS:data = 1
106        root:Packages:NIST:SAS:linear_data = 1
107
108       
109        // other variables
110        // -(hard coded right now - look for NVAR declarations)
111        Variable/G root:Packages:NIST:gBinWidth=1               //uses global preference
112        Variable/G root:Packages:NIST:SAS:gisLogScale=0
113        String/G root:Packages:NIST:SAS:FileList = "SASCALC"
114       
115        // for the panel
116//      Variable/G root:Packages:NIST:SAS:gInst=3               //or 7 for NG7
117        String/G root:Packages:NIST:SAS:gInstStr="NG3"          //or "NG7" or "NGA"=10m or "NGB"=NG3 moved
118        Variable/G root:Packages:NIST:SAS:gNg=0
119        Variable/G root:Packages:NIST:SAS:gTable=2              //2=chamber, 1=table
120        Variable/G root:Packages:NIST:SAS:gDetDist=1000         //sample chamber to detector in cm
121        Variable/G root:Packages:NIST:SAS:gSSD=1632             //!!SSD in cm fo 0 guides (derived from Ng)
122        Variable/G root:Packages:NIST:SAS:gOffset=0
123        Variable/G root:Packages:NIST:SAS:gSamAp=1.27           //samAp diameter in cm
124        Variable/G root:Packages:NIST:SAS:gLambda=6
125        Variable/G root:Packages:NIST:SAS:gDeltaLambda=0.125            //default value
126        String/G root:Packages:NIST:SAS:gSourceApString = "1.43 cm;2.54 cm;3.81 cm;"
127        String/G root:Packages:NIST:SAS:gDeltaLambdaStr = "0.109;0.125;0.236;"          //ng3 defaults
128        String/G root:Packages:NIST:SAS:gApPopStr = "1/16\";1/8\";3/16\";1/4\";5/16\";3/8\";7/16\";1/2\";9/16\";5/8\";11/16\";3/4\";other;"
129        Variable/G root:Packages:NIST:SAS:gSamApOther = 10              //non-standard aperture diameter, in mm
130        Variable/G root:Packages:NIST:SAS:gUsingLenses = 0              //0=no lenses, 1=lenses(or prisms)
131        Variable/G root:Packages:NIST:SAS:gModelOffsetFactor = 1
132       
133        // for the MC simulation
134        Variable/G root:Packages:NIST:SAS:doSimulation  =0              // == 1 if 1D simulated data, 0 if other from the checkbox
135        Variable/G root:Packages:NIST:SAS:gRanDateTime=datetime
136        Variable/G root:Packages:NIST:SAS:gImon = 10000
137        Variable/G root:Packages:NIST:SAS:gThick = 0.1
138        Variable/G root:Packages:NIST:SAS:gSig_incoh = 0.1
139        String/G root:Packages:NIST:SAS:gFuncStr = ""
140        Variable/G root:Packages:NIST:SAS:gR2 = 2.54/2 
141        Variable/G root:Packages:NIST:SAS:gSamTrans=0.8                 //for 1D, default value
142        Variable/G root:Packages:NIST:SAS:gCntTime = 300
143        Variable/G root:Packages:NIST:SAS:gDoMonteCarlo = 0
144        Variable/G root:Packages:NIST:SAS:gUse_MC_XOP = 1                               //set to zero to use Igor code
145        Variable/G root:Packages:NIST:SAS:gBeamStopIn = 1                       //set to zero for beamstop out (transmission)
146        Variable/G root:Packages:NIST:SAS:gRawCounts = 0
147        Variable/G root:Packages:NIST:SAS:gSaveIndex = 100
148        String/G root:Packages:NIST:SAS:gSavePrefix = "SIMUL"
149        Variable/G root:Packages:NIST:SAS:gAutoSaveIndex = 100                  //a way to set the index for automated saves
150        String/G root:Packages:NIST:SAS:gAutoSaveLabel = ""                             //a way to set the "sample" label for automated saves
151        Make/O/D/N=10 root:Packages:NIST:SAS:results = 0
152        Make/O/T/N=10 root:Packages:NIST:SAS:results_desc = {"total X-section (1/cm)","SAS X-section (1/cm)","number that scatter","number that reach detector","avg # times scattered","fraction single coherent","fraction multiple coherent","fraction multiple scattered","fraction transmitted","detector counts w/beamstop"}
153
154        Variable/G root:Packages:NIST:SAS:g_1DTotCts = 0                        //summed counts (simulated)
155        Variable/G root:Packages:NIST:SAS:g_1DEstDetCR = 0              // estimated detector count rate
156        Variable/G root:Packages:NIST:SAS:g_1DFracScatt = 0             // fraction of beam captured on detector
157        Variable/G root:Packages:NIST:SAS:g_1DEstTrans = 0              // estimated transmission of sample (OUTPUT)
158        Variable/G root:Packages:NIST:SAS:g_1D_DoABS = 1
159        Variable/G root:Packages:NIST:SAS:g_1D_AddNoise = 1
160        Variable/G root:Packages:NIST:SAS:g_MultScattFraction=0
161        Variable/G root:Packages:NIST:SAS:g_detectorEff=0.75                    //average value for most wavelengths
162        Variable/G root:Packages:NIST:SAS:g_actSimTime = 0                              //for the save
163        Variable/G root:Packages:NIST:SAS:g_SimTimeWarn = 10                    //manually set to a very large value for scripted operation
164       
165       
166        //tick labels for SDD slider
167        //userTicks={tvWave,tlblWave }
168        Make/O/D/N=5 root:Packages:NIST:SAS:tickSDDNG3,root:Packages:NIST:SAS:tickSDDNG7
169        Make/O/T/N=5 root:Packages:NIST:SAS:lblSDDNG3,root:Packages:NIST:SAS:lblSDDNG7
170        Make/O/D/N=5 root:Packages:NIST:SAS:tickSDDNGA
171        Make/O/T/N=5 root:Packages:NIST:SAS:lblSDDNGA
172        root:Packages:NIST:SAS:tickSDDNG3 = {133,400,700,1000,1317}
173        root:Packages:NIST:SAS:lblSDDNG3 = {"133","400","700","1000","1317"}
174        root:Packages:NIST:SAS:tickSDDNG7 = {100,450,800,1150,1530}
175        root:Packages:NIST:SAS:lblSDDNG7 = {"100","450","800","1150","1530"}
176        root:Packages:NIST:SAS:tickSDDNGA = {106,200,300,400,525}
177        root:Packages:NIST:SAS:lblSDDNGA = {"106","200","300","400","525"}
178//      root:Packages:NIST:SAS:tickSDDNGA = {106,200,300,400,500,525}
179//      root:Packages:NIST:SAS:lblSDDNGA = {"106","200","300","400","500","525"}
180               
181        //for the fake dependency
182        Variable/G root:Packages:NIST:SAS:gTouched=0
183        Variable/G root:Packages:NIST:SAS:gCalculate=0
184        //for plotting
185        Variable/G root:Packages:NIST:SAS:gFreezeCount=1                //start the count at 1 to keep Jeff happy
186        Variable/G root:Packages:NIST:SAS:gDoTraceOffset=0              // (1==Yes, offset 2^n), 0==turn off the offset
187       
188        // fill a fake data header
189        // fill w/default values
190        S_fillDefaultHeader(root:Packages:NIST:SAS:integersRead,root:Packages:NIST:SAS:realsRead,root:Packages:NIST:SAS:textRead)
191       
192End
193
194Function initNG3()
195
196        SetDataFolder root:Packages:NIST:SAS
197       
198        String/G gSelectedInstrument="checkNG3"
199        String/G gInstStr = "NG3"
200       
201        Variable/G s12 = 54.8
202        Variable/G d_det = 0.508
203        Variable/G a_pixel = 0.508
204        Variable/G del_r = 0.5
205        Variable/G det_width = 64.0
206        Variable/G lambda_t = 5.50
207        Variable/G l2r_lower = 132.3
208        Variable/G l2r_upper =  1317
209        Variable/G lambda_lower = 2.5
210        Variable/G lambda_upper = 20.0
211        Variable/G d_upper = 25.0
212        Variable/G bs_factor = 1.05
213        Variable/G t1 = 0.63
214        Variable/G t2 = 1.0
215        Variable/G t3 = 0.75
216        Variable/G l_gap = 100.0
217        Variable/G guide_width = 6.0
218        Variable/G idmax = 100.0
219//      //old values, from 3/2002
220//      Variable/G phi_0 = 2.95e13
221//      Variable/G b = 0.023
222//      Variable/G c = 0.023
223
224        //new values, from 11/2009 --- BeamFluxReport_2009.ifn
225        Variable/G phi_0 = 2.42e13
226        Variable/G b = 0.0
227        Variable/G c = -0.0243
228        Variable/G gGuide_loss = 0.924
229       
230//      //fwhm values (new variables) (+3, 0, -3, calibrated 2009)
231//      Variable/G fwhm_narrow = 0.109
232//      Variable/G fwhm_mid = 0.125
233//      Variable/G fwhm_wide = 0.236
234//     
235//      //source apertures (cm)
236//      Variable/G a1_0_0 = 1.43
237//      Variable/G a1_0_1 = 2.54
238//      Variable/G a1_0_2 = 3.81
239//      Variable/G a1_7_0 = 2.5 // after the polarizer         
240//      Variable/G a1_7_1 = 5.0
241//      Variable/G a1_7_1 = 0.95                // new Mar 2012 9.5 mm diameter source aperture
242//      Variable/G a1_def = 5.00
243       
244        //default configuration values
245//      ng = 0
246//      a1 = 3.81
247//      pos_table = 2
248//      l2r = 1310.0
249//      a2 = 1.27
250//      det_off = 0.0
251//      lambda = 6.0
252//      lambda_width = 0.15
253        Variable/G      l2diff = 5.0
254//     
255
256
257        UpdateSASHeader()
258       
259        SetDataFolder root:
260end
261
262Function initNG7()
263
264        SetDataFolder root:Packages:NIST:SAS
265
266        String/G gSelectedInstrument="checkNG7"
267        String/G gInstStr = "NG7"
268       
269        Variable/G s12 = 54.8
270        Variable/G d_det = 0.508
271        Variable/G a_pixel = 0.508
272        Variable/G del_r = 0.5
273        Variable/G det_width = 64.0
274        Variable/G lambda_t = 5.50
275        Variable/G l2r_lower = 100
276        Variable/G l2r_upper =  1531
277        Variable/G lambda_lower = 4.0
278        Variable/G lambda_upper = 20.0
279        Variable/G d_upper = 25.0
280        Variable/G bs_factor = 1.05
281        Variable/G t1 = 0.63
282        Variable/G t2 = 0.7
283        Variable/G t3 = 0.75
284        Variable/G l_gap = 188.0
285        Variable/G guide_width = 5.0
286        Variable/G idmax = 100.0
287       
288//      //old values, from 3/2002
289//      Variable/G phi_0 = 2.3e13
290//      Variable/G b = 0.028
291//      Variable/G c = 0.028
292
293        //new values, from 11/2009     
294        Variable/G phi_0 = 2.55e13
295        Variable/G b = 0.0395
296        Variable/G c = 0.0442
297        Variable/G gGuide_loss = 0.974
298       
299//      //fwhm values (new variables)
300//      Variable/G fwhm_narrow = 0.09
301//      Variable/G fwhm_mid = 0.115             //2009
302//      Variable/G fwhm_wide = 0.22
303//     
304//      //source apertures (cm)
305//      Variable/G a1_0_0 = 1.43
306//      Variable/G a1_0_1 = 2.22
307//      Variable/G a1_0_2 = 3.81
308//      Variable/G a1_7_0 = 5.0         // don't apply to NG7
309//      Variable/G a1_7_1 = 5.0
310//      Variable/G a1_def = 5.00
311       
312        //default configuration values
313//      ng = 0
314//      a1 = 2.22
315//      pos_table = 2
316//      l2r = 1530.0
317//      a2 = 1.27
318//      det_off = 0.0
319//      lambda = 6.0
320//      lambda_width = 0.11
321        Variable/G      l2diff = 5.0
322//     
323
324        UpdateSASHeader()
325        SetDataFolder root:
326end
327
328/// this is the (incomplete) definition of the 10m SANS instrument
329// on NG-B, which will be referred to as NGA here to keep the NG(number) notation
330// reserving NGB for the moved NG3 instrument
331// which may be simpler here to keep functions from breaking...
332//
333// Updated 24 JAN 2013 with current flux numbers from John
334//
335Function initNGA()
336
337        SetDataFolder root:Packages:NIST:SAS
338
339        String/G gSelectedInstrument="checkNGA"
340        String/G gInstStr = "NGA"
341
342        Variable/G s12 = 0                      //**            no difference between sample and huber position
343        Variable/G d_det = 0.508
344        Variable/G a_pixel = 0.508
345        Variable/G del_r = 0.5
346        Variable/G det_width = 64.0
347        Variable/G lambda_t = 5.50                              //good, Jan 2013
348        Variable/G l2r_lower = 106
349        Variable/G l2r_upper =  525
350        Variable/G lambda_lower = 3.0
351        Variable/G lambda_upper = 30.0
352        Variable/G d_upper = 25.0                       
353        Variable/G bs_factor = 1.05             
354        Variable/G t1 = 0.63                            //**good, Jan 2013
355        Variable/G t2 = 1.0                                     //**good, Jan 2013
356        Variable/G t3 = 0.75                            //**good, Jan 2013
357        Variable/G l_gap = 165                          //**good, Jan 2013
358        Variable/G guide_width = 5.0            //**good, Jan 2013
359        Variable/G idmax = 100.0                        //** max count rate per pixel
360//      current values -- Jan 2013
361        Variable/G phi_0 = 2.5e13
362        Variable/G b = 0.03
363        Variable/G c = 0.03
364
365        Variable/G gGuide_loss = 0.95
366       
367//      //fwhm values (new variables) (+3, 0, -3, calibrated 2009)
368//      Variable/G fwhm_narrow = 0.10
369//      Variable/G fwhm_mid = 0.20
370//      Variable/G fwhm_wide = 0.30
371//     
372//      //source apertures (cm)
373//      Variable/G a1_0_0 = 1.43
374//      Variable/G a1_0_1 = 2.54
375//      Variable/G a1_0_2 = 3.81
376//      Variable/G a1_7_0 = 2.5 // after the polarizer         
377//      Variable/G a1_7_1 = 5.0
378//      Variable/G a1_7_1 = 0.95                // new Mar 2012 9.5 mm diameter source aperture
379//      Variable/G a1_def = 5.00
380//     
381        //default configuration values
382//      ng = 0
383//      a1 = 3.81
384//      pos_table = 2
385//      l2r = 1310.0
386//      a2 = 1.27
387//      det_off = 0.0
388//      lambda = 6.0
389//      lambda_width = 0.15
390        Variable/G      l2diff = 5.0
391//     
392        UpdateSASHeader()
393        SetDataFolder root:
394end
395
396// as the instrument changes, fill in appropriate values into the header waves of the SAS folder
397// so that any simulation data (2D VAX) that is written out will be as correct as possible
398// -- this should be taken care of in SimulationVAXHeader(), so this is really redundant
399Function UpdateSASHeader()
400
401        Wave/T tw=root:Packages:NIST:SAS:textRead
402        // fill in the instrument
403        SVAR gInstStr = root:Packages:NIST:SAS:gInstStr
404        tw[3] = "["+gInstStr+"SANS99]"
405
406End
407
408Function S_fillDefaultHeader(iW,rW,tW)
409        Wave iW,rW
410        Wave/T tW
411
412        // text wave
413        // fill in the instrument
414        SVAR gInstStr = root:Packages:NIST:SAS:gInstStr
415        tw[3] = "["+gInstStr+"SANS99]"
416       
417        // integer wave
418        // don't need anything
419       
420        // real wave
421        rw = 0
422        rw[16] = 65             // beamcenter X (pixels)
423        rw[17] = 64             // beamcenter Y
424       
425        rw[10]  = 5.08                  //detector resolution (5mm) and calibration constants (linearity)
426        rw[11] = 10000
427        rw[12] = 0
428        rw[13] = 5.08
429        rw[14] = 10000
430        rw[15] = 0
431       
432        rw[20] = 65             // det size in cm
433        rw[18] = 6              // SDD in meters (=L2)
434       
435        rw[26] = 6              //lambda in Angstroms
436        rw[4] = 1               //transmission
437       
438        rw[21] = 76.2                   //BS diameter in mm
439        rw[23] = 50                     //A1 diameter in mm
440        rw[24] = 12.7                   //A2 diameter in mm
441        rw[25] = 7.02                   //L1 distance in meters (derived from number of guides)
442        rw[27] = 0.11                   //DL/L wavelength spread
443       
444        return(0)
445End
446
447//
448Window SASCALC_Panel()
449
450        PauseUpdate; Silent 1           // building window...
451
452// if I make the graph a subwindow in a panel, it breaks the "append 1d" from the wrapper       
453//      NewPanel/W=(5,44,463,570)/K=1 as "SASCALC"
454//      DoWindow/C SASCALC
455//      ModifyPanel cbRGB=(49151,53155,65535)
456//
457//     
458//      String fldrSav0= GetDataFolder(1)
459//      SetDataFolder root:Packages:NIST:SAS:
460//     
461//      Display/HOST=#/W=(5,200,463,570) aveint vs qval
462//      ModifyGraph mode=3
463//      ModifyGraph marker=19
464//      ModifyGraph rgb=(0,0,0)
465//      Modifygraph log=1
466//      Modifygraph grid=1
467//      Modifygraph mirror=2
468//      ModifyGraph msize(aveint)=2
469//      ErrorBars/T=0 aveint Y,wave=(sigave,sigave)
470//      Label bottom, "Q (1/A)"
471//      Label left, "Relative Intensity"
472//      legend
473//     
474//      RenameWindow #,G_aveint
475//      SetActiveSubwindow ##
476
477//// end panel commands
478
479/// draw as a graph
480        String fldrSav0= GetDataFolder(1)
481        SetDataFolder root:Packages:NIST:SAS:
482       
483        Display/W=(5,44,463,570)/K=1  aveint vs qval as "SASCALC"
484        DoWindow/C SASCALC
485        ModifyGraph cbRGB=(49151,53155,65535)
486        ModifyGraph mode=3
487        ModifyGraph marker=19
488        ModifyGraph rgb=(0,0,0)
489        Modifygraph log=1
490        Modifygraph grid=1
491        Modifygraph mirror=2
492        ModifyGraph msize(aveint)=2
493        ErrorBars/T=0 aveint Y,wave=(sigave,sigave)
494        Label bottom, "Q (1/A)"
495        Label left, "Relative Intensity"
496        legend
497       
498        ControlBar/T 200
499
500        SetDataFolder fldrSav0
501       
502        Slider SC_Slider,pos={11,46},size={150,45},proc=GuideSliderProc,live=0
503        Slider SC_Slider,limits={0,8,1},variable= root:Packages:NIST:SAS:gNg,vert= 0//,thumbColor= (1,16019,65535)
504        Slider SC_Slider_1,pos={234,45},size={150,45},proc=DetDistSliderProc,live=0
505        Slider SC_Slider_1,tkLblRot= 90,userTicks={root:Packages:NIST:SAS:tickSDDNG3,root:Packages:NIST:SAS:lblSDDNG3 }
506        Slider SC_Slider_1,limits={133,1317,1},variable= root:Packages:NIST:SAS:gDetDist,vert= 0//,thumbColor= (1,16019,65535)
507        Slider SC_Slider_2,pos={394,21},size={47,65},proc=OffsetSliderProc,live=0,ticks=4
508        Slider SC_Slider_2,limits={0,25,1},variable= root:Packages:NIST:SAS:gOffset//,thumbColor= (1,16019,65535)
509        CheckBox checkNG3,pos={20,19},size={36,14},proc=SelectInstrumentCheckProc,title="NG3"
510        CheckBox checkNG3,value=1,mode=1
511        CheckBox checkNG7,pos={66,19},size={36,14},proc=SelectInstrumentCheckProc,title="NG7"
512        CheckBox checkNG7,value=0,mode=1
513
514        CheckBox checkChamber,pos={172,48},size={57,14},proc=TableCheckProc,title="Chamber"
515        CheckBox checkChamber,value=1,mode=1
516        CheckBox checkHuber,pos={172,27},size={44,14},proc=TableCheckProc,title="Huber"
517        CheckBox checkHuber,value=0,mode=1
518//      -- hide/unhide the 10m SANS
519        if(show10mSANS)
520                CheckBox checkNGA,pos={110,19},size={40,14},proc=SelectInstrumentCheckProc,title="NGA"
521                CheckBox checkNGA,value=0,mode=1
522        endif
523//             
524        PopupMenu popup0,pos={6,94},size={76,20},proc=SourceAperturePopMenuProc
525        PopupMenu popup0,mode=1,popvalue="3.81 cm",value= root:Packages:NIST:SAS:gSourceApString
526        PopupMenu popup0_1,pos={172,72},size={49,20},proc=SampleAperturePopMenuProc
527        PopupMenu popup0_1,mode=8,popvalue="1/2\"",value= root:Packages:NIST:SAS:gApPopStr
528        SetVariable setvar0,pos={301,107},size={130,15},title="Det Dist (cm)",proc=SDDSetVarProc
529        SetVariable setvar0,limits={133,1317,1},value=root:Packages:NIST:SAS:gDetDist
530        SetVariable setvar0_1,pos={321,129},size={110,15},title="Offset (cm)",proc=OffsetSetVarProc
531        SetVariable setvar0_1,limits={0,25,1},value= root:Packages:NIST:SAS:gOffset
532        SetVariable setvar0_2,pos={6,130},size={90,15},title="Lambda",proc=LambdaSetVarProc
533        SetVariable setvar0_2,limits={4,20,0.1},value= root:Packages:NIST:SAS:gLambda
534        PopupMenu popup0_2,pos={108,127},size={55,20},proc=DeltaLambdaPopMenuProc
535        PopupMenu popup0_2,mode=2,value= root:Packages:NIST:SAS:gDeltaLambdaStr
536        Button FreezeButton title="Freeze",size={60,20},pos={180,166}
537        Button FreezeButton proc=FreezeButtonProc
538        Button ClearButton title="Clear",size={60,20},pos={250,166}
539        Button ClearButton proc=S_ClearButtonProc
540//      GroupBox group0,pos={6,1},size={108,36},title="Instrument"
541        GroupBox group0,pos={6,1},size={160,36},title="Instrument"
542        SetDataFolder fldrSav0
543       
544        SetVariable setvar0_3,pos={140,94},size={110,15},title="Diam (mm)",disable=1
545        SetVariable setvar0_3,limits={0,100,0.1},value= root:Packages:NIST:SAS:gSamApOther,proc=SampleApOtherSetVarProc
546       
547        CheckBox checkLens,pos={6,155},size={44,14},proc=LensCheckProc,title="Lenses?"
548        CheckBox checkLens,value=root:Packages:NIST:SAS:gUsingLenses
549       
550        CheckBox checkSim,pos={6,175},size={44,14},proc=SimCheckProc,title="Simulation?"
551        CheckBox checkSim,value=0
552       
553        CheckBox check0_1,pos={80,155},size={90,14},title="Offset Traces?",variable= root:Packages:NIST:SAS:gDoTraceOffset
554
555        // help, done buttons
556        Button SC_helpButton,pos={340,166},size={25,20},proc=showSASCALCHelp,title="?"
557        Button SC_helpButton,help={"Show help file for simulation of SANS Data"}
558        Button SC_DoneButton,pos={380,166},size={50,20},proc=SASCALCDoneButton,title="Done"
559        Button SC_DoneButton,help={"This button will close the panel"}
560
561        // set up a fake dependency to trigger recalculation
562        //root:Packages:NIST:SAS:gCalculate := ReCalculateInten(root:Packages:NIST:SAS:gTouched)
563EndMacro
564
565//clean up
566Proc SASCALCDoneButton(ctrlName): ButtonControl
567        String ctrlName
568        DoWindow/K SASCALC
569        DoWindow/K Trial_Configuration
570        DoWindow/K Saved_Configurations
571        DoWindow/K MC_SASCALC
572        DoWindow/K Sim_1D_Panel
573end
574
575//
576Proc showSASCALCHelp(ctrlName): ButtonControl
577        String ctrlName
578        DisplayHelpTopic/K=1/Z "SASCALC"
579        if(V_flag !=0)
580                DoAlert 0,"The SANS Simulation Help file could not be found"
581        endif
582end
583
584// based on the instrument selected...
585// set the SDD range
586// set the source aperture popup (based on NGx and number of guides)
587// set the wavelength spread popup
588//
589Function UpdateControls()
590        //poll the controls on the panel, and change needed values
591        Variable isNG3,Ng,mode
592
593        ControlInfo/W=SASCALC SC_slider
594        Ng=V_value
595        NVAR gNg = root:Packages:NIST:SAS:gNg
596        gNg = Ng                //update the global from the panel
597       
598        SVAR A1str= root:Packages:NIST:SAS:gSourceApString// = "1.43 cm;2.54 cm;3.81 cm;"
599        SVAR dlStr = root:Packages:NIST:SAS:gDeltaLambdaStr
600        SVAR selInstr = root:Packages:NIST:SAS:gInstStr
601        NVAR lambda = root:Packages:NIST:SAS:gLambda
602
603        strswitch(selInstr)     // string switch
604                case "NG3":                     //
605                        switch(ng)     
606                                case 0:
607                                        ControlInfo/W=SASCALC popup0
608                                        mode=V_value
609                                        A1str="1.43 cm;2.54 cm;3.81 cm;"
610                                        break
611        //                      case 6:                                                                 //Mar 2012 - 6 guides is OK now, 5 cm aperture present in 7th box
612        //                              A1str = "! 6 Guides invalid;"
613        //                              mode=1
614        //                              break
615                                case 7:                                                 // switched order in 2009 to keep 5 cm as default, 2.5 cm for polarizer
616                                        A1Str = "5.00 cm;2.50 cm;0.95 cm;"              // Mar 2012 - 3rd aperture added
617                                        mode = 1
618                                        break
619                                default:
620                                        A1str = "5 cm;"
621                                        mode=1
622                        endswitch
623                        //wavelength spread
624                        dlStr = "0.109;0.125;0.236;"            //updated calibration 2009
625                        Slider SC_Slider win=SASCALC,limits={0,8,1},ticks=1
626                        //detector limits
627                        Slider SC_Slider_1,win=SASCALC,limits={133,1317,1},userTicks={root:Packages:NIST:SAS:tickSDDNG3,root:Packages:NIST:SAS:lblSDDNG3 }
628                        SetVariable setvar0,win=SASCALC,limits={133,1317,1}
629                        NVAR detDist=root:Packages:NIST:SAS:gDetDist
630                        if(detDist < 133 )
631                                detDist = 133
632                        elseif (detDist > 1317 )
633                                detDist = 1317
634                        endif
635
636                        // wavelength limits
637                        SetVariable setvar0_2 win=SASCALC,limits={4,20,0.1}
638                        if(lambda < 4)
639                                lambda = 4
640                        endif
641                        if(lambda > 20)
642                                lambda = 20
643                        endif
644
645                        // un-disable the sample table position
646                        CheckBox checkChamber,win=SASCALC,disable=0
647                        CheckBox checkHuber,win=SASCALC,disable=0
648                                               
649                        break
650                                                               
651                case "NG7":                     //
652                        switch(ng)     
653                                case 0:
654                                        ControlInfo/W=SASCALC popup0
655                                        mode=V_value
656                                        A1str="1.43 cm;2.22 cm;3.81 cm;"
657                                        break
658                                default:
659                                        A1str = "5.08 cm;"
660                                        mode=1
661                        endswitch
662                       
663                        dlStr = "0.09;0.115;0.22;"
664                        Slider SC_Slider win=SASCALC,limits={0,8,1},ticks=1
665                        Slider SC_Slider_1,win=SASCALC,limits={100,1531,1},userTicks={root:Packages:NIST:SAS:tickSDDNG7,root:Packages:NIST:SAS:lblSDDNG7 }
666                        SetVariable setvar0,win=SASCALC,limits={100,1531,1}
667                       
668                        if(detDist < 100 )
669                                detDist = 100
670                        elseif (detDist > 1531 )
671                                detDist = 1531
672                        endif
673                        // wavelength limits
674                        SetVariable setvar0_2 win=SASCALC,limits={4,20,0.1}
675                        if(lambda < 4)
676                                lambda = 4
677                        endif
678                        if(lambda > 20)
679                                lambda = 20
680                        endif
681                                               
682                        // un-disable the sample table position
683                        CheckBox checkChamber,win=SASCALC,disable=0
684                        CheckBox checkHuber,win=SASCALC,disable=0
685                       
686                        break
687                       
688                case "NGA":             // 10m SANS
689                        if(ng>2)
690                                ng=2
691                                gNg = Ng                //update the global
692                        endif
693                        switch(ng)     
694                                case 0:
695                                        ControlInfo/W=SASCALC popup0
696                                        mode=V_value
697                                        A1str="1.3 cm;2.5 cm;3.8 cm;"
698                                        break
699                                default:
700                                        A1str = "5.0 cm;"
701                                        mode=1
702                        endswitch
703                       
704                        dlStr = "0.10;0.132;0.154;0.25;"
705                        Slider SC_Slider win=SASCALC,limits={0,2,1},ticks=2                     //number of guides different on 10m SANS, 3 ticks
706                        Slider SC_Slider_1,win=SASCALC,limits={106,525,1},userTicks={root:Packages:NIST:SAS:tickSDDNGA,root:Packages:NIST:SAS:lblSDDNGA }
707                        SetVariable setvar0,win=SASCALC,limits={106,525,1}
708
709                        NVAR detDist=root:Packages:NIST:SAS:gDetDist
710                        if(detDist < 106 )
711                                detDist = 106
712                        elseif (detDist > 525 )
713                                detDist = 525
714                        endif
715                       
716                        // wavelength limits
717                        SetVariable setvar0_2 win=SASCALC,limits={3,30,0.1}
718                        if(lambda < 3)
719                                lambda = 3
720                        endif
721                        if(lambda > 30)
722                                lambda = 30
723                        endif
724                                       
725                        // disable the sample table position, as long as the sample positions are identical for the 10 m
726                        CheckBox checkChamber,win=SASCALC,disable=2
727                        CheckBox checkHuber,win=SASCALC,disable=2
728
729                        break
730                       
731                default:                                                        // optional default expression executed
732                                DoAlert 0,"No matching instrument!  UpdateControls"                                     // when no case matches
733        endswitch
734       
735        // force update of the sliders
736        Slider SC_Slider,win=SASCALC,variable=root:Packages:NIST:SAS:gNg                                //guides
737        Slider SC_Slider_1,win=SASCALC,variable=root:Packages:NIST:SAS:gDetDist         //detector distance
738        Slider SC_Slider_2,win=SASCALC,variable=root:Packages:NIST:SAS:gOffset          //detector offset
739
740
741        ControlUpdate popup0
742        PopupMenu popup0,win=SASCALC,mode=mode          //source Ap
743        ControlInfo/W=SASCALC popup0
744        SourceAperturePopMenuProc("",0,S_Value)                 //send popNum==0 so recalculation won't be done
745       
746        ControlUpdate popup0_2          // delta lambda pop
747        ControlInfo/W=SASCALC popup0_2
748        DeltaLambdaPopMenuProc("",0,S_Value)            //sets the global and the wave
749End
750
751//changing the number of guides changes the SSD
752// the source aperture popup may need to be updated
753//
754Function GuideSliderProc(ctrlName,sliderValue,event)
755        String ctrlName
756        Variable sliderValue
757        Variable event  // bit field: bit 0: value set, 1: mouse down, 2: mouse up, 3: mouse moved
758       
759        Variable recalc=0
760       
761        if(event %& 0x1)        // bit 0, value set
762                if(cmpstr(ctrlName,"") != 0)            //here by direct action, so do LensCheck and recalculate
763                        recalc=1
764                        LensCheckProc("",2)             //make sure lenses are deselected
765                endif
766                sourceToSampleDist()            //updates the SSD global and wave
767                //change the sourceAp popup, SDD range, etc
768                UpdateControls()                                // the Ng global is actually set inside this function
769                ReCalculateInten(recalc)
770        endif
771        return 0
772End
773
774// changing the detector position changes the SDD
775//
776Function DetDistSliderProc(ctrlName,sliderValue,event)
777        String ctrlName
778        Variable sliderValue
779        Variable event  // bit field: bit 0: value set, 1: mouse down, 2: mouse up, 3: mouse moved
780
781        Variable recalc=0
782        if(event %& 0x1)        // bit 0, value set
783                if(cmpstr(ctrlName,"") != 0)
784                        recalc=1
785                        LensCheckProc("",2)             //make sure lenses are only selected for valid configurations
786                endif
787                sampleToDetectorDist()          //changes the SDD and wave (DetDist is the global)
788                ReCalculateInten(recalc)
789        endif
790
791        return 0
792End
793
794// change the offset
795// - changes the beamcenter (x,y) position too
796Function OffsetSliderProc(ctrlName,sliderValue,event)
797        String ctrlName
798        Variable sliderValue
799        Variable event  // bit field: bit 0: value set, 1: mouse down, 2: mouse up, 3: mouse moved
800
801        if(event %& 0x1)        // bit 0, value set
802                detectorOffset()
803                ReCalculateInten(1)
804        endif
805
806        return 0
807End
808
809// changing the instrument -
810// re-initialize the global values
811// update the controls to appropriate limits/choices
812//
813// updated for 10m SANS
814Function SelectInstrumentCheckProc(ctrlName,checked) : CheckBoxControl
815        String ctrlName
816        Variable checked
817
818
819        strswitch(ctrlName)     // string switch
820                case "checkNG3":                        //
821                        checkBox checkNG3,win=SASCALC, value=1
822                        checkBox checkNG7,win=SASCALC, value=0
823                        checkBox checkNGA,win=SASCALC, value=0
824                        initNG3()
825                        break                                           
826                case "checkNG7":                        //
827                        checkBox checkNG3,win=SASCALC, value=0
828                        checkBox checkNG7,win=SASCALC, value=1
829                        checkBox checkNGA,win=SASCALC, value=0
830                        initNG7()
831                        break
832                case "checkNGA":                // 10m SANS
833                        checkBox checkNG3,win=SASCALC, value=0
834                        checkBox checkNG7,win=SASCALC, value=0
835                        checkBox checkNGA,win=SASCALC, value=1
836                        initNGA()
837                        break
838                default:                                                        // optional default expression executed
839                                                                        // when no case matches
840        endswitch
841
842
843        LensCheckProc("",2)             //check if lenses are still valid (they won't be)
844        UpdateControls()
845        ReCalculateInten(1)
846End
847
848//changing the table position
849// changes the SSD and SDD
850Function TableCheckProc(ctrlName,checked) : CheckBoxControl
851        String ctrlName
852        Variable checked
853
854        NVAR table=root:Packages:NIST:SAS:gTable
855        if(cmpstr(ctrlName,"checkHuber")==0)
856                checkBox checkHuber,win=SASCALC, value=1
857                checkBox checkChamber,win=SASCALC, value=0
858                table=1         //in Huber position
859        else
860                checkBox checkHuber,win=SASCALC, value=0
861                checkBox checkChamber,win=SASCALC, value=1
862                table = 2               //in Sample chamber
863        endif
864        sampleToDetectorDist()
865        sourceToSampleDist()            //update
866        ReCalculateInten(1)
867End
868
869
870//lenses (or prisms) in/out changes resolution
871//
872// passing in a checked == 2 will do a check of the configuration without
873// affecting the box state
874//
875// if an invalid configuration is detected, the box is unchecked
876// and the lens flag is set to zero (=out).
877//
878// When necessary controls are "popped", a ctrlName="" is passed to signal the control
879// to NOT recalculate the intensity, and to NOT (recursively) call LensCheckProc again
880//
881// currently, the 17.2 A for lens/prism @ ng3 must be typed in
882//
883Function LensCheckProc(ctrlName,checked) : CheckBoxControl
884        String ctrlName
885        Variable checked
886
887        // don't let the box get checked if the conditions are wrong
888        // lambda != 8.09,8.4,17.2
889        // Ng != 0
890        NVAR lens = root:Packages:NIST:SAS:gUsingLenses
891        NVAR ng = root:Packages:NIST:SAS:gNg
892        NVAR lam = root:Packages:NIST:SAS:gLambda
893        NVAR dist = root:Packages:NIST:SAS:gDetDist
894//      NVAR instrument = root:Packages:NIST:SAS:instrument
895        Wave rw=root:Packages:NIST:SAS:realsRead
896       
897        SVAR selInstr = root:Packages:NIST:SAS:gInstStr
898               
899        // directly uncheck the box, just set the flag and get out
900        if(checked == 0)
901                lens = 0
902                CheckBox checkLens,win=SASCALC,value=0
903                rw[28]=0                //flag for lenses out
904                ReCalculateInten(1)
905                return(0)
906        endif
907       
908        // check the box, enforce the proper conditions
909        if(checked == 1)
910                lens = checked 
911                strswitch(selInstr)     // string switch
912                        case "NG3":
913                                dist = 1317
914                                DetDistSliderProc("",1317,1)
915                               
916                                lam = 8.4
917                                LambdaSetVarProc("",8.4,"8.4","")
918       
919                                ng=0
920                                Slider SC_Slider,win=SASCALC,variable=root:Packages:NIST:SAS:gNg
921                                GuideSliderProc("",0,1)
922
923                                PopupMenu popup0,win=SASCALC,mode=1,popvalue="1.43 cm"          //first item in source aperture menu
924                               
925                                PopupMenu popup0_2,win=SASCALC,mode=2           //deltaLambda
926                                ControlInfo/W=SASCALC popup0_2
927                                DeltaLambdaPopMenuProc("",0,S_value)                    //zero as 2nd param skips recalculation
928                                rw[28]=1                //flag for lenses in (not the true number, but OK)
929               
930                                break
931                        case "NG7":
932                                dist = 1531
933                                DetDistSliderProc("",1531,1)
934                               
935                                lam = 8.09
936                                LambdaSetVarProc("",8.09,"8.09","")
937                               
938                                ng=0
939                                Slider SC_Slider,win=SASCALC,variable=root:Packages:NIST:SAS:gNg
940                                GuideSliderProc("",0,1)
941                               
942                                PopupMenu popup0,win=SASCALC,mode=1,popvalue="1.43 cm"          //first item
943                               
944                                PopupMenu popup0_2,win=SASCALC,mode=2           //deltaLambda
945                                ControlInfo/W=SASCALC popup0_2
946                                DeltaLambdaPopMenuProc("",0,S_value)                    //zero as 2nd param skips recalculation
947                                rw[28]=1                //flag for lenses in (not the true number, but OK)
948                               
949                                break
950                        case "NGA":
951                                // 10m SANS - force no lenses for now
952                                // TODO:  -- put in CORRECT VALUES -- THESE ARE FICTIONAL
953                                lens = 0                //no lenses
954                                CheckBox checkLens,win=SASCALC,value=0
955                                rw[28]=0                //flag for lenses out
956
957                                break
958                        default:
959                                DoAlert 0,"No matching instrument! LCP"
960                endswitch
961        endif
962       
963        // this is my internal check to see if conditions are still valid
964        // I get to this point by calling this myself and passing the fictional value of (2) for the
965        // checkbox value...
966        //
967       
968        // I'll uncheck as needed
969        Variable lensNotAllowed=0
970        if(checked == 2)
971
972                // source aperture must be 1.43 cm diameter
973                // number of guides must be zero
974                Variable a1 = sourceApertureDiam()
975                if(a1 != 1.43  || Ng !=0)
976                        lensNotAllowed=1
977                endif
978       
979                // instrument specific distance requirements
980                if(cmpstr(selInstr,"NG3") == 0 && dist != 1317)
981                        lensNotAllowed=1
982                endif
983       
984                if(cmpstr(selInstr,"NG7") == 0 && dist != 1531)
985                        lensNotAllowed=1
986                endif
987               
988                // instrument specific wavelength requirements
989                if(cmpstr(selInstr,"NG3") == 0 && !(lam == 8.4 || lam == 17.2) )
990                        lensNotAllowed=1
991                endif
992               
993                if(cmpstr(selInstr,"NG7") == 0 && lam != 8.09 )
994                        lensNotAllowed=1
995                endif
996
997        // right now, if 10m instrument, no lenses allowed             
998                if(cmpstr(selInstr,"NGA") == 0)
999                        lensNotAllowed=1
1000                endif
1001               
1002        endif
1003       
1004        if(lensNotAllowed)
1005                lens = 0
1006                CheckBox checkLens,win=SASCALC,value=0
1007                rw[28]=0                //flag for lenses out
1008                return(0)
1009        endif
1010
1011        ReCalculateInten(1)
1012
1013
1014        return(1)               //return value not used
1015End
1016
1017//
1018//simulation controls as a control bar that toggles on/off to the right
1019//
1020// depending on the state of the 2D flag, open the 1d or 2d control panel
1021Function SimCheckProc(CB_Struct) : CheckBoxControl
1022        STRUCT WMCheckboxAction &CB_Struct
1023
1024
1025        if(CB_Struct.checked)
1026                NVAR do2D = root:Packages:NIST:SAS:gDoMonteCarlo
1027               
1028                if((CB_Struct.eventMod & 2^1) != 0 )            //if the shift key is down (bit 1)- go to 2D mode
1029                        do2D = 1
1030                endif
1031               
1032                if(do2D)
1033                        DoWindow/F MC_SASCALC
1034                        if(V_flag==0)
1035                                Execute "MC_SASCALC()"          //sets the variable
1036                                AutoPositionWindow/M=1/R=SASCALC MC_SASCALC
1037                        endif
1038                else
1039                        //draw 1D panel
1040                        DoWindow/F Sim_1D_Panel
1041                        if(V_flag==0)
1042                                Execute "Sim_1D_Panel()"
1043                                AutoPositionWindow/M=1/R=SASCALC Sim_1D_Panel
1044                        endif
1045                endif
1046                NVAR doSim = root:Packages:NIST:SAS:doSimulation
1047                doSim=1
1048        else
1049                //get rid of the controls (just try both)
1050                DoWindow MC_SASCALC
1051                if(V_flag!=0)
1052                        NVAR do2D = root:Packages:NIST:SAS:gDoMonteCarlo
1053                        do2D = 0
1054                        KillWindow MC_SASCALC
1055                endif
1056                DoWindow Sim_1D_Panel
1057                if(V_flag!=0)
1058                        KillWindow Sim_1D_Panel
1059                endif
1060               
1061                NVAR doSim = root:Packages:NIST:SAS:doSimulation
1062                doSim=0
1063        endif
1064
1065        return(0)
1066End
1067
1068//
1069// change the source aperture
1070//
1071Function SourceAperturePopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
1072        String ctrlName
1073        Variable popNum
1074        String popStr
1075
1076        Variable a1 = sourceApertureDiam()              //sets the new value in the wave
1077       
1078        // if LensCheckProc is calling this, don't call it again.
1079        // if this is called by a direct pop, then check
1080        if(cmpstr(ctrlName,"") != 0)
1081                LensCheckProc("",2)             //make sure lenses are only selected for valid configurations
1082        endif
1083       
1084        ReCalculateInten(popnum)                //skip the recalculation if I pass in a zero
1085End
1086
1087// set sample aperture
1088//
1089Function SampleAperturePopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
1090        String ctrlName
1091        Variable popNum
1092        String popStr
1093
1094        sampleApertureDiam()
1095        ReCalculateInten(1)
1096End
1097
1098// set sample to detector distance
1099//
1100Function SDDSetVarProc(ctrlName,varNum,varStr,varName) : SetVariableControl
1101        String ctrlName
1102        Variable varNum
1103        String varStr
1104        String varName
1105       
1106        sampleToDetectorDist()
1107        if(cmpstr(ctrlName,"") != 0)
1108                LensCheckProc("",2)             //make sure lenses are only selected for valid configurations
1109        endif
1110        ReCalculateInten(1)
1111End
1112
1113// set offset
1114// -- also changes the beamcenter (x,y)
1115//
1116Function OffsetSetVarProc(ctrlName,varNum,varStr,varName) : SetVariableControl
1117        String ctrlName
1118        Variable varNum
1119        String varStr
1120        String varName
1121
1122        detectorOffset()                //sets the offset in the wave and also the new (x,y) beamcenter
1123       
1124        ReCalculateInten(1)
1125        return(0)
1126End
1127
1128// change the wavelength
1129Function LambdaSetVarProc(ctrlName,varNum,varStr,varName) : SetVariableControl
1130        String ctrlName
1131        Variable varNum
1132        String varStr
1133        String varName
1134
1135        WAVE rw=root:Packages:NIST:SAS:realsRead
1136        Variable recalc=0
1137       
1138        rw[26] = str2num(varStr)
1139        if(cmpstr(ctrlName,"") != 0)
1140                recalc=1
1141                LensCheckProc("",2)             //make sure lenses are only selected for valid configurations
1142        endif
1143        ReCalculateInten(recalc)
1144        return(0)
1145End
1146
1147
1148// change the wavelength spread
1149Function DeltaLambdaPopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
1150        String ctrlName
1151        Variable popNum
1152        String popStr
1153
1154        NVAR dl=root:Packages:NIST:SAS:gDeltaLambda
1155        dl=str2num(popStr)
1156        WAVE rw=root:Packages:NIST:SAS:realsRead
1157        rw[27] = dl
1158        ReCalculateInten(popnum)                //skip the calculation if I pass in  zero
1159        return(0)
1160End
1161
1162
1163// calculate the intensity
1164// - either do MC or the straight calculation.
1165//
1166// *****currently the smeared calculation is turned off, by not prepending "fSmeared" to the FUNCREFs)
1167// --- the random deviate can't be calculated for the smeared model since I don't know the resolution
1168// function over an infinite q-range, just the detector. Maybe the interpolation is OK, but I
1169// don't really have a good way of testing this. Also, the resolution calculation explicitly multiplies
1170// by fShad, and this wrecks the random deviate calculation. The 2D looks great, but the probabilities
1171// are all wrong. fShad is only appropriate post-simulation.
1172//
1173//
1174// (--NO--) ALWAYS DOES THE RESOLUTION SMEARED CALCULATION
1175//  even though the unsmeared model is plotted. this is more realistic to
1176//  present to users that are planning base on what they will see in an experiment.
1177//
1178// some bits of the calculation are in a root:Simulation folder that are needed for the resolution smeared calculation
1179// all other bits (as possible) are in the SAS folder (a 2D work folder)
1180//
1181// passing in one does the calculation, "normal" or MC, depending on the global. Normal calculation is the default
1182// passing in zero from a control skips the calculation
1183//
1184Function ReCalculateInten(doIt)
1185        Variable doIt
1186       
1187        if(doIt==0)                     
1188                return(0)
1189        endif
1190       
1191        // update the wave with the beamstop diameter here, since I don't know what
1192        // combinations of parameters will change the BS - but anytime the curve is
1193        // recalculated, or the text displayed, the right BS must be present
1194        beamstopDiam()
1195       
1196        // generate the resolution waves first, so they are present for a smearing calculation
1197        // average the "fake" 2d data now to generate the smearing information
1198        S_CircularAverageTo1D("SAS")
1199        WAVE aveint=root:Packages:NIST:SAS:aveint
1200        WAVE qval=root:Packages:NIST:SAS:qval
1201        WAVE sigave=root:Packages:NIST:SAS:sigave
1202        WAVE SigmaQ=root:Packages:NIST:SAS:sigmaQ
1203        WAVE qbar=root:Packages:NIST:SAS:qbar
1204        WAVE fSubS=root:Packages:NIST:SAS:fSubS
1205       
1206        //generate a "fake" 1d data folder/set named "Simulation"
1207        Fake1DDataFolder(qval,aveint,sigave,sigmaQ,qbar,fSubs,"Simulation")
1208       
1209        // do the simulation here, or not
1210        Variable r1,xCtr,yCtr,sdd,pixSize,wavelength
1211        String coefStr,abortStr,str
1212
1213        // now the cases are: simulation (0|1), 1D (default) or 2D (hidden)
1214        NVAR doMonteCarlo = root:Packages:NIST:SAS:gDoMonteCarlo                // == 1 if 2D MonteCarlo set by hidden flag
1215        NVAR doSimulation = root:Packages:NIST:SAS:doSimulation         // == 1 if 1D simulated data, 0 if other from the checkbox
1216        SVAR funcStr = root:Packages:NIST:SAS:gFuncStr          //set by the popup
1217
1218        if(doSimulation == 1)
1219                if(doMonteCarlo == 1)
1220                        //2D simulation (in MultiScatter_MonteCarlo_2D.ipf)
1221                       
1222                        Simulate_2D_MC(funcStr,aveint,qval,sigave,sigmaq,qbar,fsubs)
1223                       
1224                        //end 2D simulation
1225                else
1226                        //1D simulation
1227                       
1228                        if(exists(funcStr) != 0)
1229                               
1230                                Simulate_1D(funcStr,aveint,qval,sigave,sigmaq,qbar,fsubs)
1231                               
1232                        else
1233                                //no function plotted, no simulation can be done
1234                                DoAlert 0,"No function is selected or plotted, so no simulation is done. The default Debye function is used."
1235               
1236                                aveint = S_Debye(1000,100,0.0,qval)
1237                                aveint *= fSubS         // multiply either estimate by beamstop shadowing
1238                                sigave = 0              //reset for model calculation
1239                        endif
1240                       
1241                endif // end 1D simulation
1242        else
1243                //no simulation
1244               
1245                aveint = S_Debye(1000,100,0.0,qval)
1246                aveint *= fSubS         // multiply either estimate by beamstop shadowing
1247                sigave = 0              //reset for model calculation
1248               
1249                //end no simulation     
1250        endif
1251       
1252
1253        //display the configuration text in a separate notebook
1254        DisplayConfigurationText()
1255       
1256        return(0)
1257End
1258
1259//freezes the current configuration
1260// -1- duplicates the trace on the graph
1261// -2- copies the configuration text to a second notebook window for printing
1262Function FreezeButtonProc(ctrlName) : ButtonControl
1263        String ctrlName
1264
1265        String str=""
1266        NVAR ct=root:Packages:NIST:SAS:gFreezeCount
1267       
1268       
1269        SetDataFolder root:Packages:NIST:SAS
1270       
1271        Duplicate/O aveint,$("aveint_"+num2str(ct))
1272        Duplicate/O qval,$("qval_"+num2str(ct))
1273        Duplicate/O sigave,$("sigave_"+num2str(ct))
1274        Appendtograph $("aveint_"+num2str(ct)) vs $("qval_"+num2str(ct))
1275        ModifyGraph mode($("aveint_"+num2str(ct)))=3
1276        ModifyGraph marker($("aveint_"+num2str(ct)))=19
1277        ModifyGraph msize($("aveint_"+num2str(ct)))=2
1278        ErrorBars/T=0 $("aveint_"+num2str(ct)) Y,wave=($("sigave_"+num2str(ct)),$("sigave_"+num2str(ct)))
1279       
1280        switch(mod(ct,10))      // 10 different colors - black is the unfrozen color
1281                case 0:
1282                        ModifyGraph rgb($("aveint_"+num2str(ct)))=(65535,16385,16385)
1283                        break
1284                case 1:
1285                        ModifyGraph rgb($("aveint_"+num2str(ct)))=(2,39321,1)
1286                        break
1287                case 2:
1288                        ModifyGraph rgb($("aveint_"+num2str(ct)))=(0,0,65535)
1289                        break
1290                case 3:
1291                        ModifyGraph rgb($("aveint_"+num2str(ct)))=(39321,1,31457)
1292                        break
1293                case 4:
1294                        ModifyGraph rgb($("aveint_"+num2str(ct)))=(48059,48059,48059)
1295                        break
1296                case 5:
1297                        ModifyGraph rgb($("aveint_"+num2str(ct)))=(65535,32768,32768)
1298                        break
1299                case 6:
1300                        ModifyGraph rgb($("aveint_"+num2str(ct)))=(0,65535,0)
1301                        break
1302                case 7:
1303                        ModifyGraph rgb($("aveint_"+num2str(ct)))=(16385,65535,65535)
1304                        break
1305                case 8:
1306                        ModifyGraph rgb($("aveint_"+num2str(ct)))=(65535,32768,58981)
1307                        break
1308                case 9:
1309                        ModifyGraph rgb($("aveint_"+num2str(ct)))=(36873,14755,58982)
1310                        break
1311        endswitch
1312       
1313        NVAR doTraceOffset = root:Packages:NIST:SAS:gDoTraceOffset
1314        NVAR offset = root:Packages:NIST:SAS:gModelOffsetFactor
1315        if(doTraceOffset)
1316                offset = 2^ct
1317                //multiply by current offset (>=1)
1318                Wave inten = $("aveint_"+num2str(ct))
1319                inten *= offset
1320                //      Print "new offset = ",offset
1321        endif
1322       
1323        ct +=1
1324        SetDataFolder root:
1325       
1326        // create or append the configuration to a new notebook
1327        if(WinType("Saved_Configurations")==0)
1328                NewNotebook/F=1/N=Saved_Configurations /W=(480,400,880,725)
1329                DoWindow/F SASCALC              //return focus to SASCALC window
1330        endif
1331        //append the text
1332        sprintf str,"\rConfiguration #%d\r",ct-1
1333        Notebook Saved_Configurations showRuler=0,defaultTab=20,selection={endOfFile, endOfFile}
1334        Notebook Saved_Configurations font="Monaco",fSize=10,fstyle=1,text=str          //bold
1335        Notebook Saved_Configurations font="Monaco",fSize=10,fstyle=0,text=SetConfigurationText()
1336        return(0)
1337End
1338
1339//clears the frozen traces on the graph, asks if you want to clear the saved text
1340//
1341Function S_ClearButtonProc(ctrlName) : ButtonControl
1342        String ctrlName
1343
1344        NVAR ct=root:Packages:NIST:SAS:gFreezeCount
1345        Variable ii
1346        Setdatafolder root:Packages:NIST:SAS
1347        for(ii=ct-1;ii>=1;ii-=1)
1348        //remove all traces, replace aveint
1349        // kill all waves _ct
1350                RemoveFromGraph $("aveint_"+num2str(ii))
1351                Killwaves/Z $("aveint_"+num2str(ii)),$("qval_"+num2str(ii))
1352        endfor
1353        ct=1
1354        setdatafolder root:
1355       
1356        DoAlert 1,"Do you also want to clear the \"Saved Configurations\" text?"
1357        if(V_flag == 1)         // yes
1358                DoWindow/K Saved_Configurations
1359        endif
1360       
1361        //reset offset value
1362        NVAR offset = root:Packages:NIST:SAS:gModelOffsetFactor
1363        offset = 1
1364        ReCalculateInten(1)
1365        return(0)
1366End
1367
1368
1369///////////////////////////////////////////////////////////
1370// 19MAR07 uses correction for beamstop diameter projection to get shadow factor correct
1371//
1372Function S_CircularAverageTo1D(type)
1373        String type
1374       
1375        Variable isCircular = 1
1376       
1377        //type is the data type to do the averaging on, and will be set as the current folder
1378        //get the current displayed data (so the correct folder is used)
1379        String destPath = "root:Packages:NIST:"+type
1380       
1381        //
1382        Variable xcenter,ycenter,x0,y0,sx,sx3,sy,sy3,dtsize,dtdist,dr,ddr
1383        Variable lambda,trans
1384        WAVE reals = $(destPath + ":RealsRead")
1385//      WAVE/T textread = $(destPath + ":TextRead")
1386//      String fileStr = textread[3]
1387       
1388        // center of detector, for non-linear corrections
1389        Variable pixelsX=128,pixelsY=128
1390       
1391        xcenter = pixelsX/2 + 0.5               // == 64.5 for 128x128 Ordela
1392        ycenter = pixelsY/2 + 0.5               // == 64.5 for 128x128 Ordela
1393       
1394        // beam center, in pixels
1395        x0 = reals[16]
1396        y0 = reals[17]
1397        //detector calibration constants
1398        sx = reals[10]          //mm/pixel (x)
1399        sx3 = reals[11]         //nonlinear coeff
1400        sy = reals[13]          //mm/pixel (y)
1401        sy3 = reals[14]         //nonlinear coeff
1402       
1403        dtsize = 10*reals[20]           //det size in mm
1404        dtdist = 1000*reals[18]         // det distance in mm
1405       
1406        NVAR binWidth=root:Packages:NIST:gBinWidth
1407//      Variable binWidth = 1
1408       
1409        dr = binWidth           // ***********annulus width set by user, default is one***********
1410        ddr = dr*sx             //step size, in mm (this value should be passed to the resolution calculation, not dr 18NOV03)
1411               
1412        Variable rcentr,large_num,small_num,dtdis2,nq,xoffst,dxbm,dybm,ii
1413        Variable phi_rad,dphi_rad,phi_x,phi_y
1414        Variable forward,mirror
1415       
1416        String side = "both"
1417//      side = StringByKey("SIDE",keyListStr,"=",";")
1418//      Print "side = ",side
1419       
1420        /// data wave is data in the current folder which was set at the top of the function
1421        WAVE data=$(destPath + ":data")
1422
1423// fake mask that uses all of the detector
1424        Make/D/O/N=(pixelsX,pixelsY) $(destPath + ":mask")
1425        Wave mask = $(destPath + ":mask")
1426        mask = 0
1427        //three pixels all around
1428        mask[0,2][] = 1
1429        mask[125,127][] = 1
1430        mask[][0,2] = 1
1431        mask[][125,127] = 1
1432        //
1433        //pixels within rcentr of beam center are broken into 9 parts (units of mm)
1434        rcentr = 100            //original
1435//      rcentr = 0
1436        // values for error if unable to estimate value
1437        //large_num = 1e10
1438        large_num = 1           //1e10 value (typically sig of last data point) plots poorly, arb set to 1
1439        small_num = 1e-10
1440       
1441        // output wave are expected to exist (?) initialized to zero, what length?
1442        // 200 points on VAX --- use 300 here, or more if SAXS data is used with 1024x1024 detector (1000 pts seems good)
1443        Variable defWavePts=500
1444        Make/O/D/N=(defWavePts) $(destPath + ":qval"),$(destPath + ":aveint")
1445        Make/O/D/N=(defWavePts) $(destPath + ":ncells"),$(destPath + ":dsq"),$(destPath + ":sigave")
1446        Make/O/D/N=(defWavePts) $(destPath + ":SigmaQ"),$(destPath + ":fSubS"),$(destPath + ":QBar")
1447
1448        WAVE qval = $(destPath + ":qval")
1449        WAVE aveint = $(destPath + ":aveint")
1450        WAVE ncells = $(destPath + ":ncells")
1451        WAVE dsq = $(destPath + ":dsq")
1452        WAVE sigave = $(destPath + ":sigave")
1453        WAVE qbar = $(destPath + ":QBar")
1454        WAVE sigmaq = $(destPath + ":SigmaQ")
1455        WAVE fsubs = $(destPath + ":fSubS")
1456       
1457        qval = 0
1458        aveint = 0
1459        ncells = 0
1460        dsq = 0
1461        sigave = 0
1462        qbar = 0
1463        sigmaq = 0
1464        fsubs = 0
1465
1466        dtdis2 = dtdist^2
1467        nq = 1
1468        xoffst=0
1469        //distance of beam center from detector center
1470        dxbm = S_FX(x0,sx3,xcenter,sx)
1471        dybm = S_FY(y0,sy3,ycenter,sy)
1472               
1473        //BEGIN AVERAGE **********
1474        Variable xi,dxi,dx,jj,data_pixel,yj,dyj,dy,mask_val=0.1
1475        Variable dr2,nd,fd,nd2,ll,kk,dxx,dyy,ir,dphi_p
1476       
1477        // IGOR arrays are indexed from [0][0], FORTAN from (1,1) (and the detector too)
1478        // loop index corresponds to FORTRAN (old code)
1479        // and the IGOR array indices must be adjusted (-1) to the correct address
1480        ii=1
1481        do
1482                xi = ii
1483                dxi = S_FX(xi,sx3,xcenter,sx)
1484                dx = dxi-dxbm           //dx and dy are in mm
1485               
1486                jj = 1
1487                do
1488                        data_pixel = data[ii-1][jj-1]           //assign to local variable
1489                        yj = jj
1490                        dyj = S_FY(yj,sy3,ycenter,sy)
1491                        dy = dyj - dybm
1492                        if(!(mask[ii-1][jj-1]))                 //masked pixels = 1, skip if masked (this way works...)
1493                                dr2 = (dx^2 + dy^2)^(0.5)               //distance from beam center NOTE dr2 used here - dr used above
1494                                if(dr2>rcentr)          //keep pixel whole
1495                                        nd = 1
1496                                        fd = 1
1497                                else                            //break pixel into 9 equal parts
1498                                        nd = 3
1499                                        fd = 2
1500                                endif
1501                                nd2 = nd^2
1502                                ll = 1          //"el-el" loop index
1503                                do
1504                                        dxx = dx + (ll - fd)*sx/3
1505                                        kk = 1
1506                                        do
1507                                                dyy = dy + (kk - fd)*sy/3
1508                                                if(isCircular)
1509                                                        //circular average, use all pixels
1510                                                        //(increment)
1511                                                        nq = S_IncrementPixel(data_pixel,ddr,dxx,dyy,aveint,dsq,ncells,nq,nd2)
1512                                                else
1513                                                        //a sector average - determine azimuthal angle
1514                                                        dphi_p = S_dphi_pixel(dxx,dyy,phi_x,phi_y)
1515                                                        if(dphi_p < dphi_rad)
1516                                                                forward = 1                     //within forward sector
1517                                                        else
1518                                                                forward = 0
1519                                                        Endif
1520                                                        if((Pi - dphi_p) < dphi_rad)
1521                                                                mirror = 1              //within mirror sector
1522                                                        else
1523                                                                mirror = 0
1524                                                        Endif
1525                                                        //check if pixel lies within allowed sector(s)
1526                                                        if(cmpstr(side,"both")==0)              //both sectors
1527                                                                if ( mirror || forward)
1528                                                                        //increment
1529                                                                        nq = S_IncrementPixel(data_pixel,ddr,dxx,dyy,aveint,dsq,ncells,nq,nd2)
1530                                                                Endif
1531                                                        else
1532                                                                if(cmpstr(side,"right")==0)             //forward sector only
1533                                                                        if(forward)
1534                                                                                //increment
1535                                                                                nq = S_IncrementPixel(data_pixel,ddr,dxx,dyy,aveint,dsq,ncells,nq,nd2)
1536                                                                        Endif
1537                                                                else                    //mirror sector only
1538                                                                        if(mirror)
1539                                                                                //increment
1540                                                                                nq = S_IncrementPixel(data_pixel,ddr,dxx,dyy,aveint,dsq,ncells,nq,nd2)
1541                                                                        Endif
1542                                                                Endif
1543                                                        Endif           //allowable sectors
1544                                                Endif   //circular or sector check
1545                                                kk+=1
1546                                        while(kk<=nd)
1547                                        ll += 1
1548                                while(ll<=nd)
1549                        Endif           //masked pixel check
1550                        jj += 1
1551                while (jj<=pixelsY)
1552                ii += 1
1553        while(ii<=pixelsX)              //end of the averaging
1554               
1555        //compute q-values and errors
1556        Variable ntotal,rr,theta,avesq,aveisq,var
1557       
1558        lambda = reals[26]
1559        ntotal = 0
1560        kk = 1
1561        do
1562                rr = (2*kk-1)*ddr/2
1563                theta = 0.5*atan(rr/dtdist)
1564                qval[kk-1] = (4*Pi/lambda)*sin(theta)
1565                if(ncells[kk-1] == 0)
1566                        //no pixels in annuli, data unknown
1567                        aveint[kk-1] = 0
1568                        sigave[kk-1] = large_num
1569                else
1570                        if(ncells[kk-1] <= 1)
1571                                //need more than one pixel to determine error
1572                                aveint[kk-1] = aveint[kk-1]/ncells[kk-1]
1573                                sigave[kk-1] = large_num
1574                        else
1575                                //assume that the intensity in each pixel in annuli is normally
1576                                // distributed about mean...
1577                                aveint[kk-1] = aveint[kk-1]/ncells[kk-1]
1578                                avesq = aveint[kk-1]^2
1579                                aveisq = dsq[kk-1]/ncells[kk-1]
1580                                var = aveisq-avesq
1581                                if(var<=0)
1582                                        sigave[kk-1] = small_num
1583                                else
1584                                        sigave[kk-1] = sqrt(var/(ncells[kk-1] - 1))
1585                                endif
1586                        endif
1587                endif
1588                ntotal += ncells[kk-1]
1589                kk+=1
1590        while(kk<=nq)
1591       
1592        //Print "NQ = ",nq
1593        // data waves were defined as 300 points (=defWavePts), but now have less than that (nq) points
1594        // use DeletePoints to remove junk from end of waves
1595        //WaveStats would be a more foolproof implementation, to get the # points in the wave
1596        Variable startElement,numElements
1597        startElement = nq
1598        numElements = defWavePts - startElement
1599        DeletePoints startElement,numElements, qval,aveint,ncells,dsq,sigave
1600       
1601        //////////////end of VAX sector_ave()
1602               
1603
1604
1605// ***************************************************************
1606//
1607// Do the extra 3 columns of resolution calculations starting here.
1608//
1609// ***************************************************************
1610
1611        Variable L2 = reals[18]
1612        Variable BS = reals[21]         //this the diameter is stored in mm
1613//  SRK - why was I using the projected diameter of the beam stop?? I added a step at the beginning of every recalculation
1614// of the intensity to get the right beamstop diameter into RealsRead...
1615//      Variable BS = beamstopDiamProjection(1) * 10            //calculated projection in cm *10 = mm
1616        Variable S1 = reals[23]
1617        Variable S2 = reals[24]
1618        Variable L1 = reals[25]
1619        lambda = reals[26]
1620        Variable lambdaWidth = reals[27]
1621
1622        Variable DDet, apOff
1623        //typical value for NG3 and NG7 - distance between sample aperture and sample in (cm)
1624        apOff=5.0
1625        // hard wire value for Ordela detectors
1626        DDet = 0.5              // resolution in cm
1627        //      String detStr=textRead[9]
1628        //      DDet = DetectorPixelResolution(fileStr,detStr)          //needs detector type and beamline
1629
1630        //Go from 0 to nq doing the calc for all three values at
1631        //every Q value
1632
1633        ii=0
1634        Variable ret1,ret2,ret3
1635        do
1636                S_getResolution(qval[ii],lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,ddr,ret1,ret2,ret3)
1637                sigmaq[ii] = ret1       //res_wave[0]
1638                qbar[ii] = ret2         //res_wave[1]
1639                fsubs[ii] = ret3                //res_wave[2]
1640                ii+=1
1641        while(ii<nq)
1642        DeletePoints startElement,numElements, sigmaq, qbar, fsubs
1643
1644        fsubs += 1e-8           //keep the values from being too small
1645
1646// End of resolution calculations
1647// ***************************************************************
1648       
1649        //get rid of the default mask, if one was created (it is in the current folder)
1650        //don't just kill "mask" since it might be pointing to the one in the MSK folder
1651        Killwaves/Z $(destPath+":mask")
1652       
1653        //return to root folder (redundant)
1654        SetDataFolder root:
1655       
1656        Return 0
1657End
1658
1659//returns nq, new number of q-values
1660//arrays aveint,dsq,ncells are also changed by this function
1661//
1662Function S_IncrementPixel(dataPixel,ddr,dxx,dyy,aveint,dsq,ncells,nq,nd2)
1663        Variable dataPixel,ddr,dxx,dyy
1664        Wave aveint,dsq,ncells
1665        Variable nq,nd2
1666       
1667        Variable ir
1668       
1669        ir = trunc(sqrt(dxx*dxx+dyy*dyy)/ddr)+1
1670        if (ir>nq)
1671                nq = ir         //resets maximum number of q-values
1672        endif
1673        aveint[ir-1] += dataPixel/nd2           //ir-1 must be used, since ir is physical
1674        dsq[ir-1] += dataPixel*dataPixel/nd2
1675        ncells[ir-1] += 1/nd2
1676       
1677        Return nq
1678End
1679
1680//function determines azimuthal angle dphi that a vector connecting
1681//center of detector to pixel makes with respect to vector
1682//at chosen azimuthal angle phi -> [cos(phi),sin(phi)] = [phi_x,phi_y]
1683//dphi is always positive, varying from 0 to Pi
1684//
1685Function S_dphi_pixel(dxx,dyy,phi_x,phi_y)
1686        Variable dxx,dyy,phi_x,phi_y
1687       
1688        Variable val,rr,dot_prod
1689       
1690        rr = sqrt(dxx^2 + dyy^2)
1691        dot_prod = (dxx*phi_x + dyy*phi_y)/rr
1692        //? correct for roundoff error? - is this necessary in IGOR, w/ double precision?
1693        if(dot_prod > 1)
1694                dot_prod =1
1695        Endif
1696        if(dot_prod < -1)
1697                dot_prod = -1
1698        Endif
1699       
1700        val = acos(dot_prod)
1701       
1702        return val
1703
1704End
1705
1706//calculates the x distance from the center of the detector, w/nonlinear corrections
1707//
1708Function S_FX(xx,sx3,xcenter,sx)               
1709        Variable xx,sx3,xcenter,sx
1710       
1711        Variable retval
1712       
1713        retval = sx3*tan((xx-xcenter)*sx/sx3)
1714        Return retval
1715End
1716
1717//calculates the y distance from the center of the detector, w/nonlinear corrections
1718//
1719Function S_FY(yy,sy3,ycenter,sy)               
1720        Variable yy,sy3,ycenter,sy
1721       
1722        Variable retval
1723       
1724        retval = sy3*tan((yy-ycenter)*sy/sy3)
1725        Return retval
1726End
1727
1728//**********************
1729// Resolution calculation - used by the averaging routines
1730// to calculate the resolution function at each q-value
1731// - the return value is not used
1732//
1733// equivalent to John's routine on the VAX Q_SIGMA_AVE.FOR
1734// Incorporates eqn. 3-15 from J. Appl. Cryst. (1995) v. 28 p105-114
1735//
1736Function/S S_getResolution(inQ,lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,del_r,SigmaQ,QBar,fSubS)
1737        Variable inQ, lambda, lambdaWidth, DDet, apOff, S1, S2, L1, L2, BS, del_r
1738        Variable &fSubS, &QBar, &SigmaQ         //these are the output quantities at the input Q value
1739       
1740        //lots of calculation variables
1741        Variable a2, q_small, lp, v_lambda, v_b, v_d, vz, yg, v_g
1742        Variable r0, delta, inc_gamma, fr, fv, rmd, v_r1, rm, v_r
1743
1744        //Constants
1745        //Variable del_r = .1
1746        Variable vz_1 = 3.956e5         //velocity [cm/s] of 1 A neutron
1747        Variable g = 981.0                              //gravity acceleration [cm/s^2]
1748
1749        String results
1750        results ="Failure"
1751       
1752        NVAR usingLenses = root:Packages:NIST:SAS:gUsingLenses
1753
1754        //rename for working variables,  these must be gotten from global
1755        //variables
1756
1757//      Variable wLam, wLW, wL1, wL2, wS1, wS2
1758//      Variable wBS, wDDet, wApOff
1759//      wLam = lambda
1760//      wLW = lambdaWidth
1761//      wDDet = DDet
1762//      wApOff = apOff
1763        S1 *= 0.5*0.1                   //convert to radius and [cm]
1764        S2 *= 0.5*0.1
1765
1766        L1 *= 100.0                     // [cm]
1767        L1 -= apOff                             //correct the distance
1768
1769        L2 *= 100.0
1770        L2 += apOff
1771
1772        BS *= 0.5*0.1                   //convert to radius and [cm]
1773        del_r *= 0.1                            //width of annulus, convert mm to [cm]
1774       
1775        //Start resolution calculation
1776        a2 = S1*L2/L1 + S2*(L1+L2)/L1
1777        q_small = 2.0*Pi*(BS-a2)*(1.0-lambdaWidth)/(lambda*L2)
1778        lp = 1.0/( 1.0/L1 + 1.0/L2)
1779
1780        v_lambda = lambdaWidth^2/6.0
1781       
1782        if(usingLenses==1)                      //SRK 2007
1783                v_b = 0.25*(S1*L2/L1)^2 +0.25*(2/3)*(lambdaWidth/lambda)^2*(S2*L2/lp)^2         //correction to 2nd term
1784        else
1785                v_b = 0.25*(S1*L2/L1)^2 +0.25*(S2*L2/lp)^2              //original form
1786        endif
1787       
1788        v_d = (DDet/2.3548)^2 + del_r^2/12.0
1789        vz = vz_1 / lambda
1790        yg = 0.5*g*L2*(L1+L2)/vz^2
1791        v_g = 2.0*(2.0*yg^2*v_lambda)                                   //factor of 2 correction, B. Hammouda, 2007
1792
1793        r0 = L2*tan(2.0*asin(lambda*inQ/(4.0*Pi) ))
1794        delta = 0.5*(BS - r0)^2/v_d
1795
1796        if (r0 < BS)
1797                inc_gamma=exp(gammln(1.5))*(1-gammp(1.5,delta))
1798        else
1799                inc_gamma=exp(gammln(1.5))*(1+gammp(1.5,delta))
1800        endif
1801
1802        fSubS = 0.5*(1.0+erf( (r0-BS)/sqrt(2.0*v_d) ) )
1803        if (fSubS <= 0.0)
1804                fSubS = 1.e-10
1805        endif
1806        fr = 1.0 + sqrt(v_d)*exp(-1.0*delta) /(r0*fSubS*sqrt(2.0*Pi))
1807        fv = inc_gamma/(fSubS*sqrt(Pi)) - r0^2*(fr-1.0)^2/v_d
1808
1809        rmd = fr*r0
1810        v_r1 = v_b + fv*v_d +v_g
1811
1812        rm = rmd + 0.5*v_r1/rmd
1813        v_r = v_r1 - 0.5*(v_r1/rmd)^2
1814        if (v_r < 0.0)
1815                v_r = 0.0
1816        endif
1817        QBar = (4.0*Pi/lambda)*sin(0.5*atan(rm/L2))
1818        SigmaQ = QBar*sqrt(v_r/rmd^2 +v_lambda)
1819       
1820        results = "success"
1821        Return results
1822End
1823
1824Function S_Debye(scale,rg,bkg,x)
1825        Variable scale,rg,bkg
1826        Variable x
1827       
1828        // variables are:
1829        //[0] scale factor
1830        //[1] radius of gyration [A]
1831        //[2] background        [cm-1]
1832       
1833        // calculates (scale*debye)+bkg
1834        Variable Pq,qr2
1835       
1836        qr2=(x*rg)^2
1837        Pq = 2*(exp(-(qr2))-1+qr2)/qr2^2
1838       
1839        //scale
1840        Pq *= scale
1841        // then add in the background
1842        return (Pq+bkg)
1843End
1844
1845
1846Function S_SphereForm(scale,radius,delrho,bkg,x)                               
1847        Variable scale,radius,delrho,bkg
1848        Variable x
1849       
1850        // variables are:                                                       
1851        //[0] scale
1852        //[1] radius (A)
1853        //[2] delrho (A-2)
1854        //[3] background (cm-1)
1855       
1856//      Variable scale,radius,delrho,bkg                               
1857//      scale = w[0]
1858//      radius = w[1]
1859//      delrho = w[2]
1860//      bkg = w[3]
1861       
1862       
1863        // calculates scale * f^2/Vol where f=Vol*3*delrho*((sin(qr)-qrcos(qr))/qr^3
1864        // and is rescaled to give [=] cm^-1
1865       
1866        Variable bes,f,vol,f2
1867        //
1868        //handle q==0 separately
1869        If(x==0)
1870                f = 4/3*pi*radius^3*delrho*delrho*scale*1e8 + bkg
1871                return(f)
1872        Endif
1873       
1874        bes = 3*(sin(x*radius)-x*radius*cos(x*radius))/x^3/radius^3
1875        vol = 4*pi/3*radius^3
1876        f = vol*bes*delrho              // [=] A
1877        // normalize to single particle volume, convert to 1/cm
1878        f2 = f * f / vol * 1.0e8                // [=] 1/cm
1879       
1880        return (scale*f2+bkg)   // Scale, then add in the background
1881       
1882End
1883
1884Function/S SetConfigurationText()
1885
1886        String str="",temp
1887
1888        SetDataFolder root:Packages:NIST:SAS
1889       
1890        NVAR numberOfGuides=gNg
1891        NVAR gTable=gTable              //2=chamber, 1=table
1892        NVAR wavelength=gLambda
1893        NVAR lambdaWidth=gDeltaLambda
1894//      NVAR instrument = instrument
1895        NVAR L2diff = L2diff
1896   NVAR lens = root:Packages:NIST:SAS:gUsingLenses
1897        SVAR/Z aStr = root:Packages:NIST:gAngstStr
1898        SVAR selInstr = root:Packages:NIST:SAS:gInstStr
1899
1900       
1901        sprintf temp,"Source Aperture Diameter =\t\t%6.2f cm\r",sourceApertureDiam()
1902        str += temp
1903        sprintf temp,"Source to Sample =\t\t\t\t%6.0f cm\r",sourceToSampleDist()
1904        str += temp
1905        sprintf temp,"Sample Aperture to Detector =\t%6.0f cm\r",sampleToDetectorDist() + L2diff
1906        str += temp
1907        sprintf temp,"Beam diameter =\t\t\t\t\t%6.2f cm\r",beamDiameter("maximum")
1908        str += temp
1909        sprintf temp,"Beamstop diameter =\t\t\t\t%6.2f inches\r",beamstopDiam()/2.54
1910        str += temp
1911        sprintf temp,"Minimum Q-value =\t\t\t\t%6.4f 1/%s (sigQ/Q = %3.1f %%)\r",qMin(),aStr,deltaQ(qMin())
1912        str += temp
1913        sprintf temp,"Maximum Horizontal Q-value =\t%6.4f 1/%s\r",qMaxHoriz(),aStr
1914        str += temp
1915        sprintf temp,"Maximum Vertical Q-value =\t\t%6.4f 1/%s\r",qMaxVert(),aStr
1916        str += temp
1917        sprintf temp,"Maximum Q-value =\t\t\t\t%6.4f 1/%s (sigQ/Q = %3.1f %%)\r",qMaxCorner(),aStr,deltaQ(qMaxCorner())
1918        str += temp
1919        sprintf temp,"Beam Intensity =\t\t\t\t%.0f counts/s\r",beamIntensity()
1920        str += temp
1921        sprintf temp,"Figure of Merit =\t\t\t\t%3.3g %s^2/s\r",figureOfMerit(),aStr
1922        str += temp
1923        sprintf temp,"Attenuator transmission =\t\t%3.3g = Atten # %d\r",attenuatorTransmission(),attenuatorNumber()
1924        str += temp
1925//     
1926//      // add text of the user-edited values
1927//      //
1928        sprintf temp,"***************** %s *** %s *****************\r",selInstr,selInstr
1929        str += temp
1930        sprintf temp,"Sample Aperture Diameter =\t\t\t\t%.2f cm\r",sampleApertureDiam()
1931        str += temp
1932        sprintf temp,"Number of Guides =\t\t\t\t\t\t%d \r", numberOfGuides
1933        str += temp
1934        sprintf temp,"Sample Chamber to Detector =\t\t\t%.1f cm\r", chamberToDetectorDist()
1935        str += temp
1936        if(gTable==1)
1937                sprintf temp,"Sample Position is \t\t\t\t\t\tHuber\r"
1938        else
1939                sprintf temp,"Sample Position is \t\t\t\t\t\tChamber\r"
1940        endif
1941        str += temp
1942        sprintf temp,"Detector Offset =\t\t\t\t\t\t%.1f cm\r", detectorOffset()
1943        str += temp
1944        sprintf temp,"Neutron Wavelength =\t\t\t\t\t%.2f %s\r", wavelength,aStr
1945        str += temp
1946        sprintf temp,"Wavelength Spread, FWHM =\t\t\t\t%.3f\r", lambdaWidth
1947        str += temp
1948        sprintf temp,"Sample Aperture to Sample Position =\t%.2f cm\r", L2Diff
1949        str += temp
1950        if(lens==1)
1951                sprintf temp,"Lenses are IN\r"
1952        else
1953                sprintf temp,"Lenses are OUT\r"
1954        endif
1955        str += temp
1956       
1957   setDataFolder root:
1958   return str                   
1959End
1960
1961Function DisplayConfigurationText()
1962
1963        if(WinType("Trial_Configuration")==0)
1964                NewNotebook/F=0/K=1/N=Trial_Configuration /W=(480,44,880,369)
1965        endif
1966        //replace the text
1967        Notebook Trial_Configuration selection={startOfFile, endOfFile}
1968        Notebook Trial_Configuration font="Monaco",fSize=10,text=SetConfigurationText()
1969        return(0)
1970end
1971
1972//parses the control for A1 diam
1973// updates the wave
1974Function sourceApertureDiam()
1975        ControlInfo/W=SASCALC popup0
1976        Variable diam
1977        sscanf S_Value, "%g cm", diam
1978        WAVE rw=root:Packages:NIST:SAS:realsRead
1979        rw[23] = diam*10                        //sample aperture diameter in mm
1980        return(diam)
1981end
1982
1983// change the sample aperture to a non-standard value
1984Function SampleApOtherSetVarProc(ctrlName,varNum,varStr,varName) : SetVariableControl
1985        String ctrlName
1986        Variable varNum
1987        String varStr
1988        String varName
1989               
1990        WAVE rw=root:Packages:NIST:SAS:realsRead
1991        rw[24] = varNum                 //sample aperture diameter in mm
1992        ReCalculateInten(1)
1993        return(0)
1994End
1995
1996//parses the control for A2 diam
1997// updates the wave and global
1998// returns a2 in cm
1999Function sampleApertureDiam()
2000        ControlInfo/W=SASCALC popup0_1
2001       
2002//      Print "In sampleApertureDiam()"
2003        //set the global
2004        NVAR a2=root:Packages:NIST:SAS:gSamAp
2005       
2006        if(cmpstr(S_Value,"other") == 0)                // "other" selected
2007                //enable the setvar, diameter in mm!
2008                SetVariable setvar0_3,win=SASCALC, disable=0
2009                // read its value (a global)
2010                NVAR a2other = root:Packages:NIST:SAS:gSamApOther
2011                a2=a2other/10                           //a2 in cm
2012        else
2013                SetVariable setvar0_3,win=SASCALC, disable=1
2014                //1st item is 1/16", popup steps by 1/16"
2015                a2 = 2.54/16.0 * (V_Value)                      //convert to cm         
2016        endif
2017        WAVE rw=root:Packages:NIST:SAS:realsRead
2018        rw[24] = a2*10                  //sample aperture diameter in mm
2019       
2020        return(a2)
2021end
2022
2023//1=huber 2=chamber
2024Function tableposition()
2025        ControlInfo/W=SASCALC checkHuber
2026        if(V_Value)
2027                return(1)               //huber
2028        else
2029                return(2)               //chamber
2030        endif
2031End
2032
2033//compute SSD and update both the global and the wave
2034//
2035// for the 10m SANS, table position is inline, so S12 = 0
2036//
2037//
2038Function sourceToSampleDist()
2039
2040        NVAR NG=root:Packages:NIST:SAS:gNg
2041        NVAR S12 = root:Packages:NIST:SAS:S12
2042        NVAR L2Diff = root:Packages:NIST:SAS:L2Diff
2043        NVAR SSD = root:Packages:NIST:SAS:gSSD
2044//      NVAR instrument = root:Packages:NIST:SAS:instrument
2045        SVAR selInstr = root:Packages:NIST:SAS:gInstStr
2046
2047        Variable NGA_gap = 61.9         // extra distance between a1 and beginning of guide 1 on NGA
2048       
2049        strswitch(selInstr)     // string switch
2050                case "NG3":
2051                case "NG7":
2052                        // NG3 and NG7 are both the same
2053                        SSD = 1632 - 155*NG - s12*(2-tableposition()) - L2Diff
2054                        break
2055                case "NGA":
2056                        // 10m SANS handled differently
2057                        // s12 == 0 by definition
2058                        // -- 16JAN13 - these are now correct values
2059                        if(ng==0)
2060                                SSD = 513 - L2diff
2061                        else                   
2062                                SSD = 513 - NGA_gap - 150*NG - s12*(2-tableposition()) - L2Diff
2063                        endif
2064                        break
2065                default:
2066                        DoAlert 0,"No matching instrument! sourceToSampleDist"
2067        endswitch
2068
2069       
2070        WAVE rw=root:Packages:NIST:SAS:realsRead
2071        rw[25] = SSD/100                // in meters
2072        return(SSD)
2073End
2074
2075
2076// not part of SASCALC, but can be used to convert the SSD to number of guides
2077//
2078// SSD in meters
2079//
2080Function numGuides(SSD)
2081        variable SSD
2082       
2083        Variable Ng
2084       
2085        //NVAR instrument = root:Packages:NIST:SAS:instrument
2086        SVAR selInstr = root:Packages:NIST:SAS:gInstStr
2087
2088        Variable NGA_gap = 61.9         // extra distance between a1 and beginning of guide 1 on NGA
2089
2090        strswitch(selInstr)     // string switch
2091                case "NG3":
2092                case "NG7":
2093                        // NG3 and NG7 are both the same
2094                        Ng = SSD*100 + 5 - 1632
2095                        Ng /= -155
2096       
2097                        break
2098                case "NGA":
2099                        // 10m SANS handled differently
2100                        // -- 16JAN13 - these are now correct values
2101                        Ng = 513 - NGA_gap - SSD*100 -5
2102                        Ng /= 150
2103       
2104                        if(ng < 0)
2105                                ng=0
2106                        endif
2107                       
2108                        break
2109                default:
2110                       
2111        endswitch
2112//      Print "Ng = ",Ng
2113
2114        Ng = abs(round(Ng))
2115        return(Ng)
2116End
2117
2118
2119//returns the offset value
2120// slider and setVar are linked to the same global
2121// updates the wave and changes the beamcenter (x,y) in the wave
2122//
2123// does not account for the fall due to gravity in y-direction
2124Function detectorOffset()
2125       
2126        WAVE rw=root:Packages:NIST:SAS:RealsRead
2127        NVAR val = root:Packages:NIST:SAS:gOffset
2128        rw[19] = val            // already in cm
2129        //move the beamcenter, make it an integer value for the MC simulation
2130        rw[16] = 64  + round(2*rw[19]) + 0.5            //approximate beam X is 64 w/no offset, 114 w/25 cm offset
2131        rw[17] = 64     + 0.5 //typical value
2132
2133        return(val)
2134end
2135
2136//returns the detector distance (slider and setVar are linked by the global)
2137//
2138Function chamberToDetectorDist()
2139
2140        NVAR val = root:Packages:NIST:SAS:gDetDist
2141        return(val)
2142End
2143
2144//sets the SDD (slider and setVar are linked by the global and is the detector position
2145//  relative to the chamber)
2146// updates the wave
2147Function sampleToDetectorDist()
2148
2149        NVAR detDist = root:Packages:NIST:SAS:gDetDist
2150        NVAR S12 = root:Packages:NIST:SAS:S12
2151        WAVE rw=root:Packages:NIST:SAS:RealsRead       
2152        Variable SDD   
2153       
2154        SDD = detDist + s12*(2-tableposition())
2155        rw[18] = SDD/100                // convert to meters for header
2156        return(SDD)
2157End
2158
2159//direction = one of "vertical;horizontal;maximum;"
2160// all of this is bypassed if the lenses are in
2161//
2162Function beamDiameter(direction)
2163        String direction
2164
2165        NVAR lens = root:Packages:NIST:SAS:gUsingLenses
2166        if(lens)
2167                return sourceApertureDiam()
2168        endif
2169       
2170    Variable l1 = sourceToSampleDist()
2171    Variable l2 //= sampleAperToDetDist()
2172    Variable d1,d2,bh,bv,bm,umbra,a1,a2
2173   
2174    NVAR L2diff = root:Packages:NIST:SAS:L2diff
2175    NVAR lambda = root:Packages:NIST:SAS:gLambda
2176    NVAR lambda_width = root:Packages:NIST:SAS:gDeltaLambda
2177    NVAR bs_factor = root:Packages:NIST:SAS:bs_factor
2178   
2179    l2 = sampleToDetectorDist() + L2diff
2180    a1 = sourceApertureDiam()
2181    a2 = sampleApertureDiam()
2182   
2183    d1 = a1*l2/l1
2184    d2 = a2*(l1+l2)/l1
2185    bh = d1+d2          //beam size in horizontal direction
2186    umbra = abs(d1-d2)
2187    //vertical spreading due to gravity
2188    bv = bh + 1.25e-8*(l1+l2)*l2*lambda*lambda*lambda_width
2189    bm = (bs_factor*bh > bv) ? bs_factor*bh : bv //use the larger of horiz*safety or vertical
2190   
2191    strswitch(direction)        // string switch
2192        case "vertical":                // execute if case matches expression
2193                return(bv)
2194                break                                           // exit from switch
2195        case "horizontal":              // execute if case matches expression
2196                return(bh)
2197                break
2198        case "maximum":         // execute if case matches expression
2199                return(bm)
2200                break
2201        default:                                                        // optional default expression executed
2202                return(bm)                                              // when no case matches
2203    endswitch
2204End
2205
2206//on NG3 and NG7, allowable sizes are 1,2,3,4" diameter
2207//will return values larger than 4.0*2.54 if a larger beam is needed
2208//
2209// - in an approximate way, account for lenses
2210Function beamstopDiam()
2211
2212        NVAR yesLens = root:Packages:NIST:SAS:gUsingLenses
2213        Variable bm=0
2214        Variable bs=0.0
2215   
2216        if(yesLens)
2217                //bm = sourceApertureDiam()             //ideal result, not needed
2218                bs = 1                                                          //force the diameter to 1"
2219        else
2220                bm = beamDiameter("maximum")
2221                do
2222                bs += 1
2223           while ( (bs*2.54 < bm) || (bs > 30.0))                       //30 = ridiculous limit to avoid inf loop
2224        endif
2225
2226        //update the wave
2227        WAVE rw=root:Packages:NIST:SAS:realsRead
2228        rw[21] = bs*25.4                //store the BS diameter in mm
2229       
2230    return (bs*2.54)            //return diameter in cm, not inches for txt
2231End
2232
2233//returns the projected diameter of the beamstop at the anode plane.
2234// most noticeable at short SDD
2235//if flag == 0 use conservative estimate = largest diameter (for SASCALC, default)
2236//if flag != 0 use point aperture = average diameter (for resolution calculation)
2237Function beamstopDiamProjection(flag)
2238        Variable flag
2239       
2240        NVAR L2diff = root:Packages:NIST:SAS:L2diff
2241        Variable a2 = sampleApertureDiam()
2242        Variable bs = beamstopDiam()
2243        Variable l2, LB, BS_P
2244   
2245        l2 = sampleToDetectorDist() + L2diff
2246        LB = 20.1 + 1.61*BS                     //distance in cm from beamstop to anode plane (empirical)
2247        if(flag==0)
2248                BS_P = bs + (bs+a2)*lb/(l2-lb)          //diameter of shadow from parallax
2249        else
2250                BS_P = bs + bs*lb/(l2-lb)               //diameter of shadow, point A2
2251        endif
2252        return (bs_p)           //return projected diameter in cm
2253End
2254
2255// 19MAR07 - using correction from John for an estimate of the shadow of the beamstop
2256// at the detection plane. This is a noticeable effect at short SDD, where the projected
2257// diameter of the beamstop is much larger than the physical diameter.
2258Function qMin()
2259
2260    Variable l2s = sampleToDetectorDist()       //distance from sample to detector in cm
2261//    Variable bs = beamstopDiam()              //beamstop diameter in cm
2262    Variable bs_p = beamstopDiamProjection(0)           //projected beamstop diameter in cm
2263    NVAR lambda = root:Packages:NIST:SAS:gLambda
2264    NVAR d_det = root:Packages:NIST:SAS:d_det           //cm
2265    NVAR a_pixel = root:Packages:NIST:SAS:a_pixel       //cm
2266
2267    return( (pi/lambda)*(bs_p + d_det + a_pixel)/l2s )          //use bs_p rather than bs
2268   // return( (pi/lambda)*(bs + d_det + a_pixel)/l2s )          //use bs (incorrect)
2269End
2270
2271Function qMaxVert()
2272
2273    Variable theta
2274    Variable l2s = sampleToDetectorDist()       //distance from sample to detector
2275    NVAR lambda = root:Packages:NIST:SAS:gLambda
2276        NVAR det_width = root:Packages:NIST:SAS:det_width
2277       
2278    theta = atan( (det_width/2.0)/l2s )
2279   
2280    return ( 4.0*pi/lambda * sin(theta/2.0) )
2281end
2282
2283Function qMaxCorner()
2284
2285    Variable l2s = sampleToDetectorDist()       //distance from sample to detector
2286    Variable radial
2287    NVAR lambda = root:Packages:NIST:SAS:gLambda
2288        NVAR det_off = root:Packages:NIST:SAS:gOffset
2289        NVAR det_width = root:Packages:NIST:SAS:det_width
2290
2291    radial=sqrt( (0.5*det_width)*(0.5*det_width)+(0.5*det_width+det_off)*(0.5*det_width+det_off) )
2292   
2293    return ( 4*pi/lambda*sin(0.5*atan(radial/l2s)) )
2294End
2295
2296Function qMaxHoriz()
2297
2298    Variable theta
2299    Variable l2s = sampleToDetectorDist()       //distance from sample to detector
2300    NVAR lambda = root:Packages:NIST:SAS:gLambda
2301        NVAR det_off = root:Packages:NIST:SAS:gOffset
2302        NVAR det_width = root:Packages:NIST:SAS:det_width
2303
2304    theta = atan( ((det_width/2.0)+det_off)/l2s )       //from the instance variables
2305   
2306    return ( 4.0*pi/lambda * sin(theta/2.0) )
2307End
2308
2309// calculate sigma for the resolution function at either limit of q-range
2310Function deltaQ(atQ)
2311        Variable atQ
2312       
2313    Variable k02,lp,l1,l2,sig_02,sigQ2,a1,a2
2314    NVAR l2Diff = root:Packages:NIST:SAS:L2diff
2315        NVAR lambda = root:Packages:NIST:SAS:gLambda
2316        NVAR lambda_width = root:Packages:NIST:SAS:gDeltaLambda
2317        NVAR d_det = root:Packages:NIST:SAS:d_det
2318        NVAR del_r = root:Packages:NIST:SAS:del_r
2319       
2320       
2321    l1 = sourceToSampleDist()
2322    l2 = sampleToDetectorDist() + L2diff
2323    a1 = sourceApertureDiam()
2324    a2 = sampleApertureDiam()
2325   
2326    k02 = (6.2832/lambda)*(6.2832/lambda)
2327    lp = 1/(1/l1 + 1/l2)
2328   
2329    sig_02 = (0.25*a1/l1)*(0.25*a1/l1)
2330    sig_02 += (0.25*a2/lp)*(0.25*a2/lp)
2331    sig_02 += (d_det/(2.355*l2))*(d_det/(2.355*l2))
2332    sig_02 += (del_r/l2)*(del_r/l2)/12
2333    sig_02 *= k02
2334   
2335    sigQ2 = sig_02 + (atQ*lambda_width)*(atQ*lambda_width)/6
2336
2337    return(100*sqrt(sigQ2)/atQ)
2338End
2339
2340// updated with new flux numbers from John Barker
2341// NG3 - Feb 2009
2342// NG7 - July 2009
2343//
2344// guide loss has been changed to 0.95 rather than the old value of 0.95
2345//
2346// other values are changed in the initialization routines
2347//
2348Function beamIntensity()
2349
2350    Variable alpha,f,t,t4,t5,t6,as,solid_angle,l1,d2_phi
2351    Variable a1,a2,retVal
2352    SetDataFolder root:Packages:NIST:SAS
2353    NVAR l_gap=l_gap,guide_width =guide_width,ng = gNg
2354    NVAR lambda_t=lambda_t,b=b,c=c
2355    NVAR lambda=gLambda,t1=t1,t2=t2,t3=t3,phi_0=phi_0
2356    NVAR lambda_width=gDeltaLambda
2357    NVAR guide_loss=gGuide_loss
2358   
2359    l1 = sourceToSampleDist()
2360    a1 = sourceApertureDiam()
2361    a2 = sampleApertureDiam()
2362   
2363   
2364    alpha = (a1+a2)/(2*l1)      //angular divergence of beam
2365    f = l_gap*alpha/(2*guide_width)
2366    t4 = (1-f)*(1-f)
2367    t5 = exp(ng*ln(guide_loss)) // trans losses of guides in pre-sample flight
2368    t6 = 1 - lambda*(b-(ng/8)*(b-c))            //experimental correction factor
2369    t = t1*t2*t3*t4*t5*t6
2370   
2371    as = pi/4*a2*a2             //area of sample in the beam
2372    d2_phi = phi_0/(2*pi)
2373    d2_phi *= exp(4*ln(lambda_t/lambda))
2374    d2_phi *= exp(-1*(lambda_t*lambda_t/lambda/lambda))
2375
2376    solid_angle = pi/4* (a1/l1)*(a1/l1)
2377
2378    retVal = as * d2_phi * lambda_width * solid_angle * t
2379    SetDataFolder root:
2380    return (retVal)
2381end
2382
2383Function figureOfMerit()
2384
2385        Variable bi = beamIntensity()
2386        NVAR lambda = root:Packages:NIST:SAS:gLambda
2387       
2388    return (lambda*lambda*bi)
2389End
2390
2391//estimate the number of pixels in the beam, and enforce the maximum countrate per pixel (idmax)
2392Function attenuatorTransmission()
2393
2394    Variable num_pixels,i_pix           //i_pix = id in John's notation
2395    Variable bDiam = beamDiameter("horizontal") //!! note that prev calculations used bh (horizontal)
2396    Variable atten,a2
2397    SetDataFolder root:Packages:NIST:SAS
2398    NVAR a_pixel=a_pixel,idmax=idmax
2399   
2400    a2 = sampleApertureDiam()
2401   
2402    num_pixels = pi/4*(0.5*(a2+bDiam))*(0.5*(a2+bDiam))/a_pixel/a_pixel
2403    i_pix = ( beamIntensity() )/num_pixels
2404   
2405    atten = (i_pix < idmax) ? 1.0 : idmax/i_pix
2406    SetDataFolder root:
2407    return(atten)
2408End
2409
2410// TODO_10m: is this going to be close enough? Are the steps the same?
2411Function attenuatorNumber()
2412
2413    Variable atten = attenuatorTransmission()
2414    Variable af,nf,numAtten
2415    SetDataFolder root:Packages:NIST:SAS
2416    NVAR lambda=gLambda
2417   
2418    af = 0.498 + 0.0792*lambda - 1.66e-3*lambda*lambda
2419    nf = -ln(atten)/af          //floating point
2420   
2421    numAtten = trunc(nf) + 1                    //in c, (int)nf
2422    //correct for larger step thickness at n > 6
2423    if(numAtten > 6)
2424        numAtten = 7 + trunc( (numAtten-6)/2 )          //in c, numAtten = 7 + (int)( (numAtten-6)/2 )
2425    endif
2426   
2427    SetDatafolder root:
2428    return (numAtten)
2429End
Note: See TracBrowser for help on using the repository browser.