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

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

Put I(0) errors in most of the places that I could make sense to put them. #215

Also removed FIT_Ops entirely by copying FITRPA functions to LinearizedFIts, and simply pointing FIT_Ops to include LinearizedFits? (this was done for backwards compatibility). part of ticket #275

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 = root:Packages:NIST:gAngstStr
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:myGlobals: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.