source: sans/Dev/trunk/NCNR_User_Procedures/Common/Packages/LinearizedFits/LinearizedFits_v40.ipf @ 838

Last change on this file since 838 was 770, checked in by srkline, 12 years ago

Documentation additions and help links to be rolled into the 7.04 release. There still is a little more documentaiton to finish in the ModelDocs?.

File size: 40.5 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=1.2
3#pragma IgorVersion=6.1
4
5///////////////////////////////
6//procedures for creating and initializing the Linearized FIT panel
7//global variables (numerical only) are kept in root:Packages:NIST:FIT folder
8//
9// this is based on the FIT routines in the SANS Reduction package, and has been modified here
10// only to make it independent of the Reduction routines, and into "Package" format
11//
12// These procedures WILL conflict in namespace with the SANS Reduction routines
13// in both Fit_Ops and VAX_Utils (and probably others...) so DO NOT
14// try to include these...
15//
16// SRK 11 JAN 05
17//
18// Prepended "A_" to all of the procs and functions to avoid name conflicts
19// with the FIT included in the reduction package
20// - DID NOT prepend "A_" to the loader/unloader which is unique to this package
21//
22// SEP 2010 - absorbed the duplicate procedure file FIT_Ops.
23// - removed "A_" prefix
24// - need to keep A_OpenFitPanel() in case old experiments are looking for this
25// - added the (completely unused) FITRPA procedures to this file
26//
27///////////////////////////////
28
29//main procedures to open the panel, initializing the data folder and global variables
30//as necessary. All are kept in a :FIT subfolder to avoid overlap with other variables
31//
32// To use any of the fit functions in the FIT panel, I(Q) data must already
33// be loaded into memory (using "plot" from the 1-D data operations
34// ** this may be useful to change in the future, replacing the 3 popups
35// with a list box - allowing the user to pick/load the data from the fit panel
36// and not offering any choice of q/i/s waves to use. (more consistent with the operation
37// of the FIT/RPA panel)
38//
39Proc OpenFitPanel()
40        If(WinType("FitPanel") == 0)
41                //create the necessary data folder
42                NewDataFolder/O root:Packages
43                NewDataFolder/O root:Packages:NIST
44                NewDataFolder/O root:Packages:NIST:FIT
45                //initialize the values
46                Variable/G root:Packages:NIST:FIT:gLolim = 0.02
47                Variable/G root:Packages:NIST:FIT:gUplim = 0.04
48                Variable/G root:Packages:NIST:FIT:gExpA = 1
49                Variable/G root:Packages:NIST:FIT:gExpB = 1
50                Variable/G root:Packages:NIST:FIT:gExpC = 1
51                Variable/G root:Packages:NIST:FIT:gBack = 0
52                String/G root:Packages:NIST:FIT:gDataPopList = "none"
53                FitPanel()
54        else
55                //window already exists, just bring to front for update
56                DoWindow/F FitPanel
57                CheckBox check0,value=0         //deselect the checkbox to use cursors
58        endif
59        //pop the file menu
60        FIT_FilePopMenuProc("",1,"")
61End
62
63Proc A_OpenFitPanel()
64        OpenFitPanel()
65End
66
67//the actual window recreation macro to draw the fit panel. Globals and data folder must
68// already be initialized
69Window FitPanel()
70        String angst = StrVarOrDefault("root:Packages:NIST:gAngstStr", "A" )
71//      String angst = "A"
72        PauseUpdate; Silent 1           // building window...
73        NewPanel /W=(461,46,735,455)/K=1
74        ModifyPanel cbRGB=(32768,54615,65535), fixedSize=1
75        SetDrawLayer UserBack
76        DrawText 56,20,"Select Experimental Data"
77        DrawText 66,138,"q-range to fit ("+angst+"^-1)"
78        DrawText 42,268,"Select the y and x-axis scaling"
79        DrawLine 1,21,271,21
80        DrawLine -1,272,273,272
81        DrawLine -1,140,272,140
82        PopupMenu ywave,pos={13,60},size={154,19},title="Data File"
83        PopupMenu ywave,help={"Select the experimental intensity values"}
84        PopupMenu ywave,mode=1,value=root:Packages:NIST:FIT:gDataPopList,proc=FIT_FilePopMenuProc
85        Button loadButton,pos={13,92},size={130,20},proc=FIT_Load_Proc,title="Load and Plot File"
86        Button loadButton,help={"After choosing a file, load it into memory and plot it with this button."}
87        Button helpButton,pos={237,28},size={25,20},proc=showFITHelp,title="?"
88        Button helpButton,help={"Show help file for linearized fitting"}
89        PopupMenu ymodel,pos={20,281},size={76,19},title="y-axis"
90        PopupMenu ymodel,help={"This popup selects how the y-axis will be linearized based on the chosen data"}
91        PopupMenu ymodel,mode=1,value= #"\"I;log(I);ln(I);1/I;I^a;Iq^a;I^a q^b;1/sqrt(I);ln(Iq);ln(Iq^2)\""
92        Button GoFit,pos={60,367},size={70,20},proc=DispatchModel,title="Do the Fit"
93        Button GoFit,help={"This button will do the specified fit using the selections in this panel"}
94        Button DoneButton,pos={180,367},size={50,20},proc=FITDoneButton,title="Done"
95        Button DoneButton,help={"This button will close the panel and the associated graph"}
96        SetVariable lolim,pos={64,147},size={134,17},title="Lower Limit"
97        SetVariable lolim,help={"Enter the lower q-limit to perform the fit ("+angst+"^-1)"}
98        SetVariable lolim,limits={0,5,0},value= root:Packages:NIST:FIT:gLolim
99        SetVariable uplim,pos={63,169},size={134,17},title="Upper Limit"
100        SetVariable uplim,help={"Enter the upper q-limit to perform the fit ("+angst+"^-1)"}
101        SetVariable uplim,limits={0,5,0},value= root:Packages:NIST:FIT:gUplim
102        SetVariable expa,pos={13,311},size={80,17},title="pow \"a\""
103        SetVariable expa,help={"This sets the exponent \"a\" for some y-axis formats. The value is ignored if the model does not use an adjustable exponent"}
104        SetVariable expa,limits={-2,10,0},value= root:Packages:NIST:FIT:gExpA
105        SetVariable expb,pos={98,311},size={80,17},title="pow \"b\""
106        SetVariable expb,help={"This sets the exponent \"b\" for some x-axis formats. The value is ignored if the model does not use an adjustable exponent"}
107        SetVariable expb,limits={0,10,0},value= root:Packages:NIST:FIT:gExpB
108        PopupMenu xmodel,pos={155,280},size={79,19},title="x-axis"
109        PopupMenu xmodel,help={"This popup selects how the x-axis will be linearized given the chosen data"}
110        PopupMenu xmodel,mode=1,value= #"\"q;log(q);q^2;q^c\""
111        CheckBox check0,pos={18,223},size={240,20},title="Use cursor range from FitWindow"
112        CheckBox check0,help={"Checking this will perform a fit between the cursors on the graph in FitWindow and ignore the numerical limits typed above"},value=0
113        SetVariable back,pos={70,338},size={139,17},title="background"
114        SetVariable back,help={"This constant background value will be subtracted from the experimental intensity before fitting is done"}
115        SetVariable back,limits={-Inf,Inf,0},value= root:Packages:NIST:FIT:gBack
116        SetVariable expc,pos={182,310},size={80,17},title="pow \"c\""
117        SetVariable expc,help={"This sets the exponent \"c\" for some x-axis formats. The value is ignored if the model does not use \"c\" as an adjustable exponent"}
118        SetVariable expc,limits={-10,10,0},value= root:Packages:NIST:FIT:gExpC
119        Button sh_all,pos={65,193},size={130,20},proc=ShowAllButtonProc,title="Show Full q-range"
120        Button sh_all,help={"Use this to show the entire q-range of the data rather than just the fitted range."}
121       
122        Button FIT_PathButton,pos={10,28},size={80,20},proc=FIT_PickPathButtonProc,title="Pick Path"
123
124EndMacro
125
126
127Proc FITDoneButton(ctrlName): ButtonControl
128        String ctrlName
129        DoWindow/K FitWindow
130        DoWindow/K FitPanel
131end
132
133Proc showFITHelp(ctrlName): ButtonControl
134        String ctrlName
135        DisplayHelpTopic/Z/K=1 "Linearized Fits"
136        if(V_flag != 0)
137                DoAlert 0, "The Linearized Fit Help file can not be found"
138        endif
139end
140
141//Loads the selected file for fitting
142//graphs the data as needed
143Proc FIT_Load_Proc(ctrlName): ButtonControl
144        String ctrlName
145       
146        //Load the data
147        String tempName="",partialName=""
148        Variable err
149        ControlInfo $"ywave"
150        //find the file from the partial filename
151        If( (cmpstr(S_value,"")==0) || (cmpstr(S_value,"none")==0) )
152                //null selection, or "none" from any popup
153                Abort "no file selected in popup menu"
154        else
155                //selection not null
156                partialName = S_value
157        Endif
158        //get a valid file based on this partialName and catPathName
159        tempName = FindValidFilename(partialName)
160
161        //prepend path to tempName for read routine
162        PathInfo catPathName
163       
164        tempName = S_path + tempName
165       
166        //load in the data (into the root directory)
167        A_LoadOneDDataWithName(tempName,0)              //let Rescale_Data() do the plotting
168        //Print S_fileName
169        //Print tempName
170       
171        String cleanLastFileName = CleanupName(partialName,0)
172        String dataStr = "root:"+cleanLastFileName+":"
173        tempName=dataStr + cleanLastFileName+"_q"
174        Duplicate/O $tempName xAxisWave
175        tempName=dataStr + cleanLastFileName+"_i"
176        Duplicate/O $tempName yAxisWave
177        tempName=dataStr + cleanLastFileName+"_s"
178        Duplicate/O $tempName yErrWave
179
180        //Plot, and adjust the scaling to match the axis scaling set by the popups
181        Rescale_Data(dataStr)
182       
183End
184
185//gets a valid file list (simply not the files with ".SAn" in the name)
186//
187Function FIT_FilePopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
188        String ctrlName
189        Variable popNum
190        String popStr
191       
192        String tempStr=filterButtonProc(ctrlName)
193        if(strlen(tempStr)==0)
194                tempStr = "Pick the data path"
195        Endif
196        String/G root:Packages:NIST:FIT:gDataPopList =tempStr
197        ControlUpdate ywave
198       
199End
200
201//direct porting of the fit program from the VAX, with no corrections and only
202//minor modifications of additional  linearizations and the option
203//to subtract a constant (q-independent) background value before doing any
204//of the fits. The original data on disk (and as loaded) is never modified, all
205//manipulation is done from a copy of the data.
206
207//button procedure to show the entire axis range of the data, rather than just
208//the fitted range, which is the default display after a fit is performed
209//
210Function ShowAllButtonProc(ctrlName) : ButtonControl
211        String ctrlName
212
213        //bring the FitWindow to the front and Autoscale the axes
214        DoWindow/F FitWindow
215        SetAxis/A
216End
217
218// function that takes the current dataset (already loaded)
219// and replots it based on the X/Y axis scaling selected in the popups
220// (does not fit the data)
221//
222// dataStr is the root:folder: of the data that was loaded
223Function Rescale_Data(dataStr)
224        String dataStr
225       
226        //Scaling exponents and background value
227        Variable pow_a,pow_b,pow_c,bkg
228        ControlInfo/W=FitPanel expa
229        pow_a = V_value
230        ControlInfo/W=FitPanel expb
231        pow_b = V_value
232        ControlInfo/W=FitPanel expc
233        pow_c = V_value
234        ControlInfo/W=FitPanel back
235        bkg = V_value
236       
237//check for physical limits on exponent values
238// if bad values found, alert, and reset to good values so the rescaling can continue
239        NVAR gA = root:Packages:NIST:FIT:gExpA
240        NVAR gB = root:Packages:NIST:FIT:gExpB
241        NVAR gC = root:Packages:NIST:FIT:gExpC
242        if((pow_a < -2) || (pow_a > 10))
243                DoAlert 0,"Exponent a must be in the range (-2,10) - the exponent a has been reset to 1"
244                gA = 1
245        endif
246        if((pow_b < 0) || (pow_b > 10))
247                DoAlert 0,"Exponent b must be in the range (0,10) - the exponent b has been reset to 1"
248                gB = 1
249        endif
250        //if q^c is the x-scaling, c must be be within limits and also non-zero
251        ControlInfo/W=FitPanel xModel
252        If (cmpstr("q^c",S_Value) == 0)
253                if(pow_c == 0)
254                        DoAlert 0,"Exponent c must be non-zero, c has been reset to 1"
255                        gC = 1
256                endif
257                if((pow_c < -10) || (pow_c > 10))
258                        DoAlert 0,"Exponent c must be in the range (-10,10), c has been reset to 1"
259                        gC = 1
260                endif
261        endif
262       
263        //do the rescaling of the data
264        // get the current experimental q, I, and std dev. waves (as they would be loaded )
265        String baseStr = ParseFilePath(0,dataStr,":",1,0)               //give me the last part of the path
266       
267        Wave xw = $(dataStr+baseStr+"_q")
268        Wave yw = $(dataStr+baseStr+"_i")
269        Wave ew = $(dataStr+baseStr+"_s")
270       
271        //variables set for each model to control look of graph
272        Variable xlow,xhigh,ylow,yhigh,yes_cursors
273        String xlabel,ylabel,xstr,ystr
274        //check for proper y-scaling selection, make the necessary waves
275        ControlInfo/W=FitPanel yModel
276        ystr = S_Value
277//      print "ystr = ",ystr
278        do
279                // make the new yaxis waves, including weighting wave
280                Duplicate/O yw yAxisWave,yErrWave,yWtWave,residWave
281                //subtract the background value from yAxisWave before doing any rescaling
282                yAxisWave = yw - bkg
283               
284                If (cmpstr("I",S_Value) == 0)
285                        SetScale d 0,0,"1/cm",yAxisWave
286                        yErrWave = ew
287                        yWtWave = 1/yErrWave
288                        yAxisWave = yAxisWave
289                        ylabel = "I(q)"
290                        break   
291                endif
292                If (cmpstr("ln(I)",S_Value) == 0)
293                        SetScale d 0,0,"",yAxisWave
294                        yErrWave = ew/yAxisWave
295                        yWtWave = 1/yErrWave
296                        yAxisWave = ln(yAxisWave)
297                        ylabel = "ln(I)"
298                        break   
299                endif
300                If (cmpstr("log(I)",S_Value) == 0)
301                        SetScale d 0,0,"",yAxisWave
302                        yErrWave = ew/(2.30*yAxisWave)
303                        yWtWave = 1/yErrWave
304                        yAxisWave = log(yAxisWave)
305                        ylabel = "log(I)"
306                        break   
307                endif
308                If (cmpstr("1/I",S_Value) == 0)
309                        SetScale d 0,0,"",yAxisWave
310                        yErrWave = ew/yAxisWave^2
311                        yWtWave = 1/yErrWave
312                        yAxisWave = 1/yAxisWave
313                        ylabel = "1/I"
314                        break
315                endif
316                If (cmpstr("I^a",S_Value) == 0)
317                        SetScale d 0,0,"",yAxisWave
318                        yErrWave = ew*abs(pow_a*(yAxisWave^(pow_a-1)))
319                        yWtWave = 1/yErrWave
320                        yAxisWave = yAxisWave^pow_a
321                        ylabel = "I^"+num2str(pow_a)
322                        break
323                endif
324                If (cmpstr("Iq^a",S_Value) == 0)
325                        SetScale d 0,0,"",yAxisWave
326                        yErrWave = ew*xw^pow_a
327                        yWtWave = 1/yErrWave
328                        yAxisWave = yAxisWave*xw^pow_a
329                        ylabel = "I*q^"+num2str(pow_a)
330                        break
331                endif
332                If (cmpstr("I^a q^b",S_Value) == 0)
333                        SetScale d 0,0,"",yAxisWave
334                        yErrWave = ew*abs(pow_a*(yAxisWave^(pow_a-1)))*xw^pow_b
335                        yWtWave = 1/yErrWave
336                        yAxisWave = yAxisWave^pow_a*xw^pow_b
337                        ylabel = "I^" + num2str(pow_a) + "q^"+num2str(pow_b)
338                        break
339                endif
340                If (cmpstr("1/sqrt(I)",S_Value) == 0)
341                        SetScale d 0,0,"",yAxisWave
342                        yErrWave = 0.5*ew*yAxisWave^(-1.5)
343                        yWtWave = 1/yErrWave
344                        yAxisWave = 1/sqrt(yAxisWave)
345                        ylabel = "1/sqrt(I)"
346                        break
347                endif
348                If (cmpstr("ln(Iq)",S_Value) == 0)
349                        SetScale d 0,0,"",yAxisWave
350                        yErrWave =ew/yAxisWave
351                        yWtWave = 1/yErrWave
352                        yAxisWave = ln(xw*yAxisWave)
353                        ylabel = "ln(q*I)"
354                        break
355                endif
356                If (cmpstr("ln(Iq^2)",S_Value) == 0)
357                        SetScale d 0,0,"",yAxisWave
358                        yErrWave = ew/yAxisWave
359                        yWtWave = 1/yErrWave
360                        yAxisWave = ln(xw*xw*yAxisWave)
361                        ylabel = "ln(I*q^2)"
362                        break
363                endif
364                //more ifs for each case
365               
366                // if selection not found, abort
367                DoAlert 0,"Y-axis scaling incorrect. Aborting"
368                Abort
369        while(0)        //end of "case" statement for y-axis scaling
370       
371       
372        //check for proper x-scaling selection
373        Variable low,high
374       
375        ControlInfo/W=FitPanel lolim
376        low = V_value
377        ControlInfo/W=FitPanel uplim
378        high = V_value
379        if ((high<low) || (high==low))
380                DoAlert 0,"Unphysical fitting limits - re-enter better values"
381                Abort
382        endif
383       
384        ControlInfo/W=FitPanel xModel
385        xstr = S_Value
386        do
387                // make the new yaxis wave
388                Duplicate/o xw xAxisWave
389                If (cmpstr("q",S_Value) == 0)   
390                        SetScale d 0,0,"A^-1",xAxisWave
391                        xAxisWave = xw
392                        xlabel = "q"
393                        xlow = low
394                        xhigh = high
395                        break   
396                endif
397                If (cmpstr("q^2",S_Value) == 0)
398                        SetScale d 0,0,"A^-2",xAxisWave
399                        xAxisWave = xw*xw
400                        xlabel = "q^2"
401                        xlow = low^2
402                        xhigh = high^2
403                        break   
404                endif
405                If (cmpstr("log(q)",S_Value) == 0)     
406                        SetScale d 0,0,"",xAxisWave
407                        xAxisWave = log(xw)
408                        xlabel = "log(q)"
409                        xlow = log(low)
410                        xhigh = log(high)
411                        break   
412                endif
413                If (cmpstr("q^c",S_Value) == 0)
414                        SetScale d 0,0,"",xAxisWave
415                        xAxisWave = xw^pow_c
416                        xlabel = "q^"+num2str(pow_c)
417                        xlow = low^pow_c
418                        xhigh = high^pow_c
419                        break
420                endif
421       
422                //more ifs for each case
423               
424                // if selection not found, abort
425                DoAlert 0,"X-axis scaling incorrect. Aborting"
426                Abort
427        while(0)        //end of "case" statement for x-axis scaling
428
429        //plot the data
430       
431//      String cleanLastFileName = "root:"+CleanupName(gLastFileName,0)
432        If(WinType("FitWindow") == 0)
433                Display /W=(5,42,480,400)/K=1 yAxisWave vs xAxisWave
434                ModifyGraph mode=3,standoff=0,marker=8,opaque=1
435                ErrorBars/T=0 yAxisWave Y,wave=(yErrWave,yErrWave)
436                DoWindow/C FitWindow
437        else
438                //window already exists, just bring to front for update
439                DoWindow/F FitWindow
440                // remove old text boxes
441                TextBox/K/N=text_1
442                TextBox/K/N=text_2
443                TextBox/K/N=text_3
444        endif
445        SetAxis/A
446        ModifyGraph tickUnit=1          //suppress tick units in labels
447        TextBox/C/N=textLabel/A=RB "File = "+baseStr
448        //clear the old fit from the window, if it exists
449        RemoveFromGraph/W=FitWindow/Z fit_yAxisWave
450       
451        // add the cursors if desired...       
452        //see if the user wants to use the data specified by the cursors - else use numerical values
453       
454        ControlInfo/W=FitPanel check0           //V_value = 1 if it is checked, meaning yes, use cursors
455        yes_cursors = V_value
456
457        DoWindow/F FitWindow
458        ShowInfo
459        if(yes_cursors)
460                xlow = xAxisWave[xcsr(A)]
461                xhigh = xAxisWave[xcsr(B)]
462                if(xlow > xhigh)
463                        xhigh = xlow
464                        xlow = xAxisWave[xcsr(B)]
465                endif
466//              Print xlow,xhigh
467        else
468                FindLevel/P/Q xAxisWave, xlow
469                if(V_flag == 1)                 //level NOT found
470                        DoAlert 0,"Lower q-limit not in experimental q-range. Re-enter a better value"
471                        //DoWindow/K FitWindow
472                        //Abort
473                endif
474                Cursor/P A, yAxisWave,trunc(V_LevelX)+1
475                ylow = V_LevelX
476                FindLevel/P/Q xAxisWave, xhigh
477                if(V_flag == 1)
478                        DoAlert 0,"Upper q-limit not in experimental q-range. Re-enter a better value"
479                        //DoWindow/K FitWindow
480                        //Abort
481                endif
482                Cursor/P B, yAxisWave,trunc(V_LevelX)
483                yhigh = V_LevelX
484        endif   //if(V_value)
485        //SetAxis bottom,xlow,xhigh
486        //SetAxis left,ylow,yhigh
487        Label left ylabel
488        Label bottom xlabel     //E denotes "scaling"  - may want to use "units" instead       
489
490End
491
492
493//button procedure that is activated to "DotheFit"
494//the panel is parsed for proper fitting limits
495// the appropriate linearization is formed (in the Rescale_Data() function)
496// and the fit is done,
497//and the results are plotted
498// function works in root level data folder (where the loaded 1-d data will be)
499Function DispatchModel(GoFit) : ButtonControl
500        String GoFit
501
502        //check for the FitWindow - to make sure that there is data to fit
503        If(WinType("FitWindow") == 0)           //if the window doesn't exist
504                Abort "You must Load and Plot a File before fitting the data"
505        endif
506       
507        // rescale the data, to make sure it's as selected on the panel
508        ControlInfo/W=FitPanel $"ywave"
509        String partialName = CleanupName(S_value,0)
510        Rescale_Data("root:"+partialName+":")
511       
512        // now go do the fit
513       
514// get the current low and high q values for fitting
515        Variable low,high
516       
517        ControlInfo/W=FitPanel lolim
518        low = V_value
519        ControlInfo/W=FitPanel uplim
520        high = V_value
521        if ((high<low) || (high==low))
522                DoAlert 0,"Unphysical fitting limits - re-enter better values"
523                Abort
524        endif
525
526        //try including residuals on the graph /R=residWave, explicitly place on new axis
527        //if only /R used, residuals are automatically placed on graph
528        // -- NOTE that Rescale_Data() calculates the weighting wave as 1/err (like the old days) so the flag is correctly
529        // /I=0, not /I=1
530       
531        CurveFit line yAxisWave(xcsr(A),xcsr(B)) /I=0 /X=xAxisWave /W=yWtWave /D 
532        //CurveFit line yAxisWave(xcsr(A),xcsr(B)) /X=xAxisWave /W=yWtWave  /R /D 
533        ModifyGraph rgb(fit_yAxisWave)=(0,0,0)
534// annotate graph, filtering out special cases of Guinier fits
535// Text Boxes must be used, since ControlBars on graphs DON'T print out
536       
537        // need access to Global wave, result of fit
538        //ystr and xstr are the axis strings - filter with a do-loop
539        String ystr="",xstr=""
540        //ControlInfo/W=FitPanel ywave
541        Wave xw = $("root:"+partialName+":"+partialName + "_q")
542        ControlInfo/W=FitPanel yModel
543        ystr = S_Value
544        ControlInfo/W=FitPanel xModel
545        xstr = S_Value
546       
547        WAVE W_coef=W_coef
548        WAVE W_sigma=W_sigma
549        String textstr_1,textstr_2,textstr_3 = ""
550        Variable rg,rgerr,minfit,maxfit,izerr
551       
552        textstr_1 = "Slope = " + num2str(W_coef[1]) + " ± " + num2str(W_sigma[1])
553        textstr_1 += "\rIntercept = " + num2str(W_coef[0]) + " ± " + num2str(W_sigma[0])
554        textstr_1 += "\rChi-Squared =  " + num2str(V_chisq/(V_npnts - 3))
555       
556        minfit = xw[xcsr(A)]
557        maxfit = xw[xcsr(B)]
558        textstr_2 = "Qmin =  " + num2str(minfit)
559        textstr_2 += "\rQmax =  " + num2str(maxfit)
560       
561        //model-specific calculations - I(0), Rg, etc.
562        //put these in textstr_3, at bottom
563        do
564                If (cmpstr("I",ystr) == 0)
565                        textstr_3 = "I(q=0) =  "  + num2str(W_coef[0]) +" ± "+num2str(W_sigma[0])
566                        break   
567                endif
568                If (cmpstr("ln(I)",ystr) == 0)
569                        izerr = abs(exp(W_coef[0]) - exp(W_coef[0]+W_sigma[0]))
570                        textstr_3 = "I(q=0) =  "  + num2str(exp(W_coef[0]))+" ± " + num2str(izerr)
571                        if(cmpstr("q^2",xstr) == 0)     //then a Guinier plot for a sphere (3-d)
572                                rg = sqrt(-3*W_coef[1])
573                                rgerr = 3*W_sigma[1]/(2*rg)
574                                textstr_3 += "\rRg (A) = " + num2str(rg) + " ± " + num2str(rgerr)
575                                textstr_3 += "\r" + num2str(rg*minfit) + " < Rg*q < " + num2str(rg*maxfit)
576                                break
577                        endif
578                        break   
579                endif
580                If (cmpstr("log(I)",ystr) == 0)
581                        if(cmpstr("log(q)",xstr) !=0 )  //extrapolation is nonsense
582                                textstr_3 = "I(q=0) =  "  + num2str(10^(W_coef[0]))
583                        endif
584                        break   
585                endif
586                If (cmpstr("1/I",ystr) == 0)
587                        izerr = abs(1/W_coef[0] - 1/(W_coef[0]+W_sigma[0]))
588                        textstr_3 = "I(q=0) =  "  + num2str(1/W_coef[0])+" ± " + num2str(izerr)
589                        break
590                endif
591                If (cmpstr("I^a",ystr) == 0)
592                        //nothing
593                        break
594                endif
595                If (cmpstr("Iq^a",ystr) == 0)
596                        //nothing
597                        break
598                endif
599                If (cmpstr("I^a q^b",ystr) == 0)
600                        //nothing
601                        break
602                endif
603                If (cmpstr("1/sqrt(I)",ystr) == 0)
604                        izerr = abs( (W_coef[0])^-2 - (W_coef[0]+W_sigma[0])^-2 )
605                        textstr_3 = "I(q=0) =  "  + num2str((W_coef[0])^-2)+" ± " + num2str(izerr)
606                        break
607                endif
608                If (cmpstr("ln(Iq)",ystr) == 0)
609                        //nothing
610                        if(cmpstr("q^2",xstr) == 0)     //then a x-sect Guinier plot for a rod (2-d)
611                                // rg now is NOT the radius of gyration, but the x-sect DIAMETER
612                                rg = 4*sqrt(-W_coef[1])
613                                rgerr = 8*W_sigma[1]/rg
614                                textstr_3 = "Rod diameter (A) = " + num2str(rg) + " ± " + num2str(rgerr)
615                                textstr_3 += "\r" + num2str(rg*minfit) + " < Rg*q < " + num2str(rg*maxfit)
616                                break
617                        endif
618                        break
619                endif
620                If (cmpstr("ln(Iq^2)",ystr) == 0)
621                        //nothing
622                        if(cmpstr("q^2",xstr) == 0)     //then a 1-d Guinier plot for a sheet
623                                // rg now is NOT the radius of gyration, but the thickness
624                                rg = sqrt(-12*W_coef[1])
625                                rgerr = 6*W_sigma[1]/(2*rg)
626                                textstr_3 = "Platelet thickness (A) = " + num2str(rg) + " ± " + num2str(rgerr)
627                                textstr_3 += "\r" + num2str(rg*minfit) + " < Rg*q < " + num2str(rg*maxfit)
628                                break
629                        endif
630                        break
631                endif
632               
633        while(0)
634        //kill the old textboxes, if they exist
635        TextBox/W=FitWindow/K/N=text_1
636        TextBox/W=FitWindow/K/N=text_2
637        TextBox/W=FitWindow/K/N=text_3
638        // write the new text boxes
639        TextBox/W=FitWindow/N=text_1/A=LT textstr_1
640        TextBox/W=FitWindow/N=text_2/A=LC textstr_2
641        If (cmpstr("",textstr_3) != 0)          //only display textstr_3 if it isn't null
642                TextBox/W=FitWindow/N=text_3/A=LB textstr_3
643        endif
644       
645        //adjust the plot range to reflect the actual fitted range
646        //cursors are already on the graph, done by Rescale_Data()
647        AdjustAxisToCursors()
648       
649End
650
651// adjusts both the x-axis scaling  and y-axis scaling to the cursor range
652// **cursors are already on the graph, done by Rescale_Data()
653//
654// will expand the scale to show an extra 5 points in each direction (if available)
655Function AdjustAxisToCursors()
656
657        DoWindow/F FitWindow
658        WAVE xAxisWave = root:xAxisWave
659        WAVE yAxisWave = root:yAxisWave
660        Variable xlow,xhigh,ylow,yhigh,yptlow,ypthigh
661        Variable extraPts = 5, num=numpnts(xAxisWave)
662       
663        String csrA = CsrInfo(A ,"FitWindow")
664        String csrB = CsrInfo(B ,"FitWindow")
665       
666        //x-levels, these are monotonic
667        Variable ptLow,ptHigh,tmp
668        ptLow = NumberByKey("POINT", csrA ,":" ,";")
669        ptHigh = NumberByKey("POINT", csrB ,":" ,";")
670        if(ptLow > ptHigh)
671                tmp= ptLow
672                ptLow=ptHigh
673                ptHigh=tmp
674        endif
675
676        // keep extended point range in bounds
677        ptLow = (ptLow-extraPts) >= 0 ? ptLow-extraPts : 0
678        ptHigh = (ptHigh+extraPts) <= (num-1) ? ptHigh + extraPts : num-1
679       
680        xlow = xAxisWave[ptLow]
681        xhigh = xAxisWave[ptHigh]
682//old way
683//      xlow = xAxisWave[xcsr(A)]
684//      xhigh = xAxisWave[xcsr(B)]
685//      if(xlow > xhigh)
686//              xhigh = xlow
687//              xlow = xAxisWave[xcsr(B)]
688//      endif
689       
690        //y-levels (old way)
691//      FindLevel/P/Q xAxisWave, xlow
692//      if(V_flag == 1)                 //level NOT found
693//              DoAlert 0,"Lower q-limit not in experimental q-range. Re-enter a better value"
694//      endif
695//      yptlow = V_LevelX
696//      FindLevel/P/Q xAxisWave, xhigh
697//      if(V_flag == 1)
698//              DoAlert 0,"Upper q-limit not in experimental q-range. Re-enter a better value"
699//      endif
700//      ypthigh = V_LevelX
701
702//      Print xlow,xhigh,yptlow,ypthigh
703//      Print yAxisWave[yptlow],yAxisWave[ypthigh]
704       
705
706        // make sure ylow/high are in the correct order, since the slope could be + or -
707        yhigh = max(yAxisWave[ptlow],yAxisWave[pthigh])
708        ylow = min(yAxisWave[ptlow],yAxisWave[pthigh])
709       
710//      Print ptLow,ptHigh
711//      print xlow,xhigh
712//      print ylow,yhigh
713       
714        SetAxis bottom,xlow,xhigh
715        SetAxis left ylow,yhigh
716       
717End
718
719///// procedures added from other SANS Reduction files
720//
721//
722
723//function called by the popups to get a file list of data that can be sorted
724// this procedure simply removes the raw data files from the string - there
725//can be lots of other junk present, but this is very fast...
726//
727// could also use the alternate procedure of keeping only file with the proper extension
728//
729// another possibility is to get a listing of the text files, but is unreliable on
730// Windows, where the data file must be .txt (and possibly OSX)
731//
732Function/S filterButtonProc(ctrlName)
733        String ctrlName
734
735        String list="",newList="",item=""
736        Variable num,ii
737       
738        //check for the path
739        PathInfo catPathName
740        if(V_Flag==0)
741                DoAlert 0, "Data path does not exist - pick the data path from the button on the FIT panel"
742                Return("")
743        Endif
744       
745        list = IndexedFile(catpathName,-1,"????")
746        num=ItemsInList(list,";")
747        //print "num = ",num
748        for(ii=(num-1);ii>=0;ii-=1)
749                item = StringFromList(ii, list  ,";")
750                //simply remove all that are not raw data files (SA1 SA2 SA3)
751                if( !stringmatch(item,"*.SA1*") && !stringmatch(item,"*.SA2*") && !stringmatch(item,"*.SA3*") )
752                        if( !stringmatch(item,".*") && !stringmatch(item,"*.pxp") && !stringmatch(item,"*.DIV"))                //eliminate mac "hidden" files, pxp, and div files
753                                newlist += item + ";"
754                        endif
755                endif
756        endfor
757        //remove VAX version numbers
758        newList = RemoveVersNumsFromList(newList)
759        //sort
760        newList = SortList(newList,";",0)
761
762        return newlist
763End
764
765
766
767//////////////////////////////////////// FIT RPA ///////////////////////////////////////////
768//****************************************
769//procedures for creating and initializing the FITRPA panel
770//global variables (numerical only) are kept in root:myGlobals:FITRPA folder,
771//created as needed
772//
773// very similar in function to the FIT panel
774//
775Proc OpenFitRPAPanel()
776        If(WinType("FitRPAPanel") == 0)
777                //create the necessary data folder
778                NewDataFolder/O root:myGlobals:FITRPA
779                //initialize the values
780                Variable/G root:myGlobals:FITRPA:gLolim = 0.02
781                Variable/G root:myGlobals:FITRPA:gUplim = 0.04
782                Variable/G root:myGlobals:FITRPA:gBack = 0
783                Variable/G root:myGlobals:FITRPA:gLambda = 6.0
784                PathInfo/S catPathName
785                String localpath = S_path
786                if (V_flag == 0)
787                //path does not exist - no folder selected
788                        String/G root:myGlobals:FITRPA:gPathStr = "no folder selected"
789                else
790                        String/G root:myGlobals:FITRPA:gPathStr = localpath
791                endif
792                String/G    root:myGlobals:FITRPA:gDataPopList = "none"
793                FitRPAPanel()
794        else
795                //window already exists, just bring to front for update
796                DoWindow/F FitRPAPanel
797        endif
798        //pop the menu
799        FilePopMenuProc("",1,"")
800End
801
802//used on the fit/rpa panel to select the path for the data
803// - automatically pops the file list after the new  path selection
804Function FITRPAPickPathButton(ctrlName) : ButtonControl
805        String ctrlName
806
807        Variable err = A_PickPath()             //sets global path value
808        SVAR pathStr = root:myGlobals:gCatPathStr
809       
810        //set the global string for NSORT to the selected pathname
811        String/G root:myGlobals:FITRPA:gPathStr = pathStr
812       
813        //call the popup menu proc's to re-set the menu choices
814        FilePopMenuProc("filePopup",1,"")
815       
816End
817
818//gets a valid file list (simply not the files with ".SAn" in the name)
819//
820Function FilePopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
821        String ctrlName
822        Variable popNum
823        String popStr
824
825        String tempStr=ReducedDataFileList(ctrlName)
826        if(strlen(tempStr)==0)
827                tempStr = "Pick the data path"
828        Endif
829        String/G root:myGlobals:FITRPA:gDataPopList =   tempStr //function is in NSORT.ipf
830        ControlUpdate filePopup
831       
832End
833
834
835
836// window recreation macro to draw the fit/rpa panel
837//globals and data folders must be present before drawing panel
838//
839Window FitRPAPanel()
840
841        String angst = root:Packages:NIST:gAngstStr
842        PauseUpdate; Silent 1           // building window...
843        NewPanel /W=(250,266,591,579)/K=1
844        ModifyPanel cbRGB=(32768,54528,65280)
845        ModifyPanel fixedSize=1
846        SetDrawLayer UserBack
847        SetDrawEnv fstyle= 1
848        DrawText 81,19,"Select Experimental Data"
849        SetDrawEnv fstyle= 1
850        DrawText 97,102,"q-range to fit ("+angst+"^-1)"
851        SetDrawEnv fstyle= 1
852        DrawText 87,239,"Select the fit parameters"
853        SetDrawEnv fillpat= 0
854        DrawRect 1,103,338,224
855        SetDrawEnv fillpat= 0
856        DrawRect 1,20,337,83
857        SetDrawEnv fillpat= 0
858        DrawRect 2,241,337,275
859//      Button PathButton,pos={6,26},size={80,20},proc=FitRPAPickPathButton,title="Pick Path"
860//      Button PathButton,help={"Select the local path to the folder containing your SANS data"}
861//      SetVariable setPath,pos={95,29},size={240,17},title="Path:"
862//      SetVariable setPath,help={"The current path to the local folder with SANS data"}
863//      SetVariable setPath,fSize=10
864//      SetVariable setPath,limits={0,0,0},value= root:myGlobals:FITRPA:gPathStr
865        PopupMenu filePopup,pos={8,30},size={96,21},proc=FilePopMenuProc,title="Files"
866        PopupMenu filePopup,help={"Select the data file to load."}
867        PopupMenu filePopup,mode=5,popvalue="none",value= #"root:myGlobals:FITRPA:gDataPopList"
868        SetVariable lambda,pos={111,250},size={120,18},title="Lambda ("+angst+")"
869        SetVariable lambda,help={"This sets the wavelength for the multiple scattering corrections."}
870        SetVariable lambda,limits={0,10,0},value= root:myGlobals:FITRPA:gLambda
871        Button GoFit,pos={60,286},size={80,20},proc=DoFITRPA,title="Do the Fit"
872        Button GoFit,help={"This button will do the specified fit using the selections in this panel"}
873        SetVariable lolim,pos={82,113},size={134,28},title="Lower Limit"
874        SetVariable lolim,help={"Enter the lower q-limit to perform the fit ("+angst+"^-1)"}
875        SetVariable lolim,limits={0,5,0},value= root:myGlobals:FITRPA:gLolim
876        SetVariable uplim,pos={80,140},size={134,28},title="Upper Limit"
877        SetVariable uplim,help={"Enter the upper q-limit to perform the fit ("+angst+"^-1)"}
878        SetVariable uplim,limits={0,5,0},value= root:myGlobals:FITRPA:gUplim
879        CheckBox RPA_check0,pos={64,198},size={190,20},title="Use cursor range from FitWindow"
880        CheckBox RPA_check0,help={"Checking this will perform a fit between the cursors on the graph in FitWindow and ignore the numerical limits typed above"},value=0
881        PopupMenu model,pos={3,249},size={101,21},title="Standard"
882        PopupMenu model,help={"This popup selects which standard should be used to fit this data"}
883        PopupMenu model,mode=1,popvalue="B",value= #"\"B;C;AS\""
884        Button sh_all,pos={82,168},size={130,20},proc=ShowAllButtonProc,title="Show Full q-range"
885        Button sh_all,help={"Use this to show the entire q-range of the data rather than just the fitted range."}
886        Button loadButton,pos={20,55},size={70,20},proc=FITRPA_Load_Proc,title="Load File"
887        Button loadButton,help={"After choosing a file, load it into memory and plot it with this button."}
888        Button helpButton,pos={270,55},size={25,20},proc=showFITHelp,title="?"
889        Button helpButton,help={"Show help file for RPA fitting"}
890        Button DoneButton,pos={200,286},size={50,20},proc=FITRPADoneButton,title="Done"
891        Button DoneButton,help={"This button will close the panel and the associated graph"}
892EndMacro
893
894
895Proc FITRPADoneButton(ctrlName) : ButtonControl
896        String ctrlName
897        DoWindow/K FitWindow
898        DoWindow/K FitRPAPanel
899end
900
901//dispatches the fit to the appropriate model
902//and the appropriate range, based on selections in the panel
903//
904Proc DoFITRPA(ctrlName) : ButtonControl
905        String ctrlName
906        //
907        String cleanLastFileName = CleanupName(root:Packages:NIST:gLastFileName,0)
908        String tmpStr = "root:"+cleanLastFileName+":"+cleanLastFileName
909
910        Duplicate/O $(tmpStr+"_q") xAxisWave
911        Duplicate/O $(tmpStr+"_i") yAxisWave
912        Duplicate/O $(tmpStr+"_s") yErrWave,yWtWave,residWave
913
914        yWtWave = 1/yErrWave
915       
916        String xlabel = "q (A^-1)"
917        String ylabel = "Intensity"
918        //Check to see if the FitWindow exists
919        //Plot the data in a FitWindow
920        If(WinType("FitWindow") == 0)
921                Display /W=(5,42,480,400)/K=1  yAxisWave vs xAxisWave
922                ModifyGraph mode=3,standoff=0,marker=8
923                ErrorBars/T=0 yAxisWave Y,wave=(yErrWave,yErrWave)
924                DoWindow/C FitWindow
925                ShowInfo
926        else
927                //window already exists, just bring to front for update
928                DoWindow/F FitWindow
929                // remove old text boxes
930                TextBox/K/N=text_1
931                TextBox/K/N=text_2
932                TextBox/K/N=text_3
933        endif
934       
935        //see if the user wants to use the data specified by the cursors - else use numerical values
936        Variable xlow,xhigh,ylow,yhigh,yes_cursors
937        ControlInfo/W=FitRPAPanel RPA_check0            //V_value = 1 if it is checked, meaning yes, use cursors
938        yes_cursors = V_value
939
940        ControlInfo/W=FitRPAPanel lolim
941        xlow = V_value
942        ControlInfo/W=FitRPAPanel uplim
943        xhigh = V_value
944        if(yes_cursors)
945                xlow = xAxisWave[xcsr(A)]
946                xhigh = xAxisWave[xcsr(B)]
947                if(xlow > xhigh)
948                        xhigh = xlow
949                        xlow = xAxisWave[xcsr(B)]
950                endif
951//              Print "xlow,xhigh = ",xlow,xhigh
952                ylow = yAxisWave[xcsr(A)]
953                yhigh = yAxisWave[xcsr(B)]
954                if(ylow > yhigh)
955                        ylow=yhigh
956                        yhigh = yAxisWave[xcsr(A)]
957                endif
958        else
959                FindLevel/P/Q xAxisWave, xlow
960                if(V_flag == 1)                 //level NOT found
961                        DoAlert 0,"Lower q-limit not in experimental q-range. Re-enter a better value"
962                        DoWindow/K FitWindow
963                        Abort
964                endif
965                Cursor/P A, yAxisWave,trunc(V_LevelX)+1
966                ylow = yAxisWave[V_LevelX]
967                FindLevel/P/Q xAxisWave, xhigh
968                if(V_flag == 1)
969                        DoAlert 0,"Upper q-limit not in experimental q-range. Re-enter a better value"
970                        DoWindow/K FitWindow
971                        Abort
972                endif
973                Cursor/P B, yAxisWave,trunc(V_LevelX)
974                yhigh = yAxisWave[V_LevelX]
975                if(ylow > yhigh)
976                        yhigh=ylow
977                        ylow = yAxisWave[V_levelX]
978                endif
979        endif   //if(V_value)
980        SetAxis bottom,xlow,xhigh
981       
982//      print "ylow,yhigh",ylow,yhigh
983       
984        //Get the rest of the data from the panel
985        //such as which standard, the wavelength
986        ControlInfo/W=FitRPAPanel model
987
988        //find the model name
989        String modelName = S_value
990       
991        Variable first_guess, seglength,iabs,iarb,thick
992        Make/D/O/N=2 fitParams
993       
994        seglength = 6.8
995       
996        first_guess = 1.0
997        fitParams[0] = first_guess
998        fitParams[1] = seglength
999
1000        If (cmpstr(modelName,"B")==0)
1001                iabs = BStandardFunction(fitParams,xlow)
1002                fitParams[0] = yhigh/iabs
1003//              Print fitParams[0],fitParams[1]
1004                FuncFit BStandardFunction fitParams yAxisWave(xcsr(A),xcsr(B)) /X=xAxisWave /W=yWtWave /D
1005                iarb = BStandardFunction(fitParams, 0.0)
1006                iabs = iarb/fitParams[0]
1007                thick = 0.153
1008        endif
1009        If (cmpstr(modelName,"C")==0)
1010                iabs = CStandardFunction(fitParams,xlow)
1011                fitParams[0] = yhigh/iabs
1012                FuncFit CStandardFunction fitParams yAxisWave(xcsr(A),xcsr(B)) /X=xAxisWave /W=yWtWave /D
1013                iarb = CStandardFunction(fitParams, 0.0)
1014                iabs = iarb/fitParams[0]
1015                thick= 0.153
1016        endif
1017        If (cmpstr(modelName,"AS")==0)
1018                iabs = ASStandardFunction(fitParams,xlow)
1019                fitParams[0] = yhigh/iabs
1020                FuncFit ASStandardFunction fitParams yAxisWave(xcsr(A),xcsr(B)) /X=xAxisWave /W=yWtWave /D
1021                iarb = ASStandardFunction(fitParams, 0.0)
1022                iabs = iarb/fitParams[0]
1023                thick = 0.1
1024        endif
1025        ModifyGraph rgb(fit_yAxisWave)=(0,0,0)
1026        Label left ylabel
1027        Label bottom xlabel     //E denotes "scaling"  - may want to use "units" instead       
1028
1029        ControlInfo/W=FitRPAPanel lambda
1030       
1031        Variable cor_mult = 1.0 + 2.2e-4*V_Value^2
1032       
1033        //WAVE W_coef=W_coef
1034        //WAVE W_sigma=W_sigma
1035        String textstr_1,textstr_2,textstr_3 = ""
1036        textstr_1 = "Scaling Parameter: "+num2str(fitParams[0])+" ± "+num2str(W_sigma[0])
1037        textstr_1 += "\rSegment Length: "+num2str(fitParams[1])+" ± "+num2str(W_sigma[1])
1038        textstr_1 += "\rChi-Squared =  " + num2str(V_chisq/(V_npnts - 3))
1039       
1040        textstr_2 = "Cross section at q=0:  Iabs(0) = "+num2str(iabs)+"cm\S-1\M"
1041        textstr_2 += "\rData extrapolated to q=0: Im(0) = "+num2str(iarb)+" Counts/(10\S8\M  Mon cts)"
1042        textstr_2 += "\rData corrected for multiple scattering: I(0) = "+num2str(iarb/cor_mult)+" Counts/(10\S8\M  Mon cnts)"
1043       
1044        textstr_3 = "In the ABS protocol, "
1045        textstr_3 += "\rStandard Thickness, d = "+num2str(thick)+"cm"
1046        textstr_3 += "\rI(0), Iarb(0) = "+num2str(iarb/cor_mult)+"Counts/(10\S8\M Mon cts)"
1047        textstr_3 += "\rStandard Cross Section, Iabs(0) = "+num2str(iabs)+"cm\S-1\M"
1048        TextBox/K/N=text_1
1049        TextBox/K/N=text_2
1050        TextBox/K/N=text_3
1051        TextBox/N=text_2/A=RT textstr_2
1052        TextBox/N=text_3/A=RC textstr_3
1053        TextBox/N=text_1/A=RB textstr_1
1054       
1055End
1056
1057//loads the file selected in the popup for fitting with POL
1058//standard functions. Reads the wavelength from the header, using
1059//6 A as the default
1060//plots the data in FitWindow after reading the file
1061//updates lambda and full q-range  on the Panel
1062//
1063Proc FITRPA_Load_Proc(ctrlName): ButtonControl
1064        String ctrlName
1065        //Load the data
1066        String tempName="",partialName=""
1067        Variable err
1068        ControlInfo $"filePopup"
1069        //find the file from the partial filename
1070        If( (cmpstr(S_value,"")==0) || (cmpstr(S_value,"none")==0) )
1071                //null selection, or "none" from any popup
1072                Abort "no file selected in popup menu"
1073        else
1074                //selection not null
1075                partialName = S_value
1076                //Print partialName
1077        Endif
1078        //get a valid file based on this partialName and catPathName
1079        tempName = FindValidFilename(partialName)
1080
1081        Variable lambdaFromFile=GetLambdaFromReducedData(tempName)
1082        Variable/G root:myGlobals:FITRPA:gLambda = lambdaFromFile
1083        Print "Lambda in file read as:", lambdaFromFile
1084       
1085        //prepend path to tempName for read routine
1086        PathInfo catPathName
1087        tempName = S_path + tempName
1088       
1089        //load in the data (into the root directory)
1090        LoadOneDDataWithName(tempName,0)
1091        //Print S_fileName
1092        //Print tempName
1093       
1094        String cleanLastFileName = CleanupName(root:Packages:NIST:gLastFileName,0)
1095        String tmpStr = "root:"+cleanLastFileName+":"+cleanLastFileName
1096
1097        Duplicate/o $(tmpStr+"_q") xAxisWave
1098        Duplicate/o $(tmpStr+"_i") yAxisWave
1099        Duplicate/o $(tmpStr+"_s") yErrWave
1100       
1101        Variable xmin, xmax
1102        WaveStats/Q xAxisWave
1103        root:myGlobals:FITRPA:gLolim=V_min
1104        root:myGlobals:FITRPA:gUplim=V_max
1105        ControlUpdate/W=FITRPAPanel/A
1106       
1107        //Check to see if the FitWindow exists
1108        //Plot the data in a FitWindow
1109        If(WinType("FitWindow") == 0)
1110                Display /W=(5,42,480,400)/K=1  yAxisWave vs xAxisWave
1111                ModifyGraph mode=3,standoff=0,marker=8
1112                ErrorBars/T=0 yAxisWave Y,wave=(yErrWave,yErrWave)
1113                TextBox/C/N=textLabel/A=RB "File = "+cleanLastFileName
1114                DoWindow/C FitWindow
1115                ShowInfo
1116        else
1117                //window already exists, just bring to front for update
1118                DoWindow/F FitWindow
1119                TextBox/C/N=textLabel/A=RB "File = "+cleanLastFileName
1120        endif
1121        // remove old text boxes
1122        TextBox/K/N=text_1
1123        TextBox/K/N=text_2
1124        TextBox/K/N=text_3
1125        RemoveFromGraph/W=fitWindow /Z fit_yAxisWave
1126        SetAxis/A
1127       
1128        //put cursors on the graph at first and last points
1129        Cursor/P A  yAxisWave  0
1130        Cursor/P B yAxisWave (numpnts(yAxisWave) - 1)
1131End
1132
1133//Fitting function for the POL-B standards
1134//
1135Function BStandardFunction(parameterWave, x)
1136        Wave parameterWave; Variable x
1137       
1138        //Model parameters
1139        Variable KN=4.114E-3,CH=9.613E4, CD=7.558E4, NH=1872, ND=1556
1140        Variable INC=0.32, CHIV=2.2E-6
1141        //Correction based on absolute flux measured 5/93
1142        Variable CORR = 1.1445
1143       
1144        //Local variables
1145        Variable AP2,QRGH,QRGD,IABS_RPA,IABS
1146       
1147        //Calculate the function here
1148        ap2=parameterWave[1]^2
1149        qrgh = x*sqrt(nh*ap2/6)
1150        qrgd = x*sqrt(nd*ap2/6)
1151        iabs_rpa = kn/(1/(ch*FIT_dbf(qrgh)) + 1/(cd*FIT_dbf(qrgd)) - chiv)
1152        iabs = corr*iabs_rpa + inc
1153       
1154        //return the result
1155        return parameterWave[0]*iabs
1156       
1157End
1158
1159//Fitting function for the POL-C standards
1160//
1161Function CStandardFunction(parameterWave, x)
1162        Wave parameterWave; Variable x
1163       
1164        //Model parameters
1165        Variable KN=4.114E-3,CH=2.564E5, CD=1.912E5, NH=4993, ND=3937
1166        Variable INC=0.32, CHIV=2.2E-6
1167        //Correction based on absolute flux measured 5/93
1168        Variable CORR = 1.0944
1169       
1170        //Local variables
1171        Variable AP2,QRGH,QRGD,IABS_RPA,IABS
1172       
1173        //Calculate the function here
1174        ap2=parameterWave[1]^2
1175        qrgh = x*sqrt(nh*ap2/6)
1176        qrgd = x*sqrt(nd*ap2/6)
1177        iabs_rpa = kn/(1/(ch*FIT_dbf(qrgh)) + 1/(cd*FIT_dbf(qrgd)) - chiv)
1178        iabs = corr*iabs_rpa + inc
1179       
1180        //return the result
1181        return parameterWave[0]*iabs
1182       
1183End
1184
1185//fitting function for the POL-AS standards
1186//
1187Function ASStandardFunction(parameterWave, x)
1188        Wave parameterWave; Variable x
1189       
1190        //Model parameters
1191        Variable KN=64.5,CH=1.0, CD=1.0, NH=766, ND=766
1192        Variable INC=0.32, CHIV=0.0
1193       
1194        //Local variables
1195        Variable AP2,QRGH,QRGD,IABS_RPA,IABS
1196       
1197        //Calculate the function here
1198        ap2=parameterWave[1]^2
1199        qrgh = x*sqrt(nh*ap2/6)
1200
1201//The following lines were commented out in the fortran function
1202        //qrgd = x*sqrt(nd*ap2/6)
1203        //iabs_rpa = kn/(1/(ch*FIT_dbf(qrgh)) + 1/(cd*FIT_dbf(qrgd)) - chiv)
1204
1205        iabs_rpa = kn*FIT_dbf(qrgh)
1206        iabs = iabs_rpa + inc
1207       
1208        //return the result
1209        return parameterWave[0]*iabs
1210       
1211End
1212
1213//Debye Function used for polymer standards
1214Function FIT_dbf(rgq)
1215        Variable rgq
1216        Variable x
1217       
1218        x=rgq*rgq
1219        if (x < 5.0E-3)
1220                return 1.0 - x/3 + x^2/12
1221        else
1222                return 2*(exp(-x) + x - 1)/x^2
1223        endif
1224End
1225
1226
1227//////////////////////////////// EMD FIT RPA //////////////////////////////////////
1228
1229
1230
1231
1232
1233
1234
1235
1236//procedures to clean up after itself
1237//
1238// -- note that it's never going to unload if the SANS Reduction is open too - since
1239// the old FIT_Ops was always loaded, and now points to this file.
1240//
1241Function UnloadLinFit()
1242
1243        if (WinType("FitPanel") == 7)
1244                DoWindow/K FitPanel
1245        endif
1246        if (WinType("FitWindow") != 0)
1247                DoWindow/K $"FitWindow"
1248        endif
1249        SetDataFolder root:
1250        Killwaves/Z xAxisWave,yAxisWave,yErrWave,residWave,yWtWave,fit_yAxisWave
1251       
1252        SVAR/Z fileVerExt=root:Packages:NIST:SANS_ANA_EXTENSION
1253        if(SVAR_Exists(fileVerExt) == 0)
1254                return 0
1255        endif
1256       
1257        String fname="LinearizedFits"
1258        Execute/P "DELETEINCLUDE \""+fname+fileVerExt+"\""
1259        Execute/P "COMPILEPROCEDURES "
1260end
1261
1262#if(exists("root:Packages:NIST:SANS_ANA_EXTENSION") != 0)
1263//this keeps the SANS Models menu from appearing in the SANS Reduction package
1264Menu "SANS Models"
1265        Submenu "Packages"
1266                "Unload Linear Fitting", UnloadLinFit()
1267        End
1268end
1269
1270#endif
1271
1272Function FIT_PickPathButtonProc(ctrlName) : ButtonControl
1273        String ctrlName
1274
1275        A_PickPath()
1276        //pop the file menu
1277        FIT_FilePopMenuProc("",1,"")
1278End
Note: See TracBrowser for help on using the repository browser.