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

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

Changes to utility functions to properly list the raw data from the 10m SANS (SA4)

Added a utility function to patch BS xPos in 10m data files so that they will be recognized as transmission files. ICE is currently not writing out the BS xPos to the file. This is done in batch mode, similar to what was done for the 8m SANS.

Some changes to the simulation code to permit easier scripting.

Additions to SASCALC for the 10m SANS. Dimensions from John. Still need attenuator table and flux.

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