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

Last change on this file since 1247 was 1219, checked in by srkline, 3 years ago

Corrections to the NGB30mSANS attenuator tables (for 3A data only).

Corrections to the sample aperture units on VSANS (change in NICE on 5/22/19).

Additions for the super white beam mode on VSANS - still in progress.

File size: 41.7 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
527        if(IgorVersion() < 8)
528                maxLength = 25
529        else
530                maxLength = 40
531        endif
532       
533        if(strlen(partialName) > maxLength)
534                // get user input, from a list of all of the data folder names
535                String dfList = sortList(GetAList(4))
536                String dataFolder=""
537                Prompt dataFolder,"Data files to choose from...",popup,dfList
538
539                DoPrompt "Select data set",dataFolder
540                if(V_Flag==1)           //user canceled
541                        SetDataFolder root:
542                        return(1)
543                endif
544                partialName = dataFolder
545        endif
546        Rescale_Data("root:"+partialName+":")
547       
548        // now go do the fit
549       
550// get the current low and high q values for fitting
551        Variable low,high
552       
553        ControlInfo/W=FitPanel lolim
554        low = V_value
555        ControlInfo/W=FitPanel uplim
556        high = V_value
557        if ((high<low) || (high==low))
558                DoAlert 0,"Unphysical fitting limits - re-enter better values"
559                Abort
560        endif
561
562        //try including residuals on the graph /R=residWave, explicitly place on new axis
563        //if only /R used, residuals are automatically placed on graph
564        // -- NOTE that Rescale_Data() calculates the weighting wave as 1/err (like the old days) so the flag is correctly
565        // /I=0, not /I=1
566       
567        CurveFit line yAxisWave(xcsr(A),xcsr(B)) /I=0 /X=xAxisWave /W=yWtWave /D 
568        //CurveFit line yAxisWave(xcsr(A),xcsr(B)) /X=xAxisWave /W=yWtWave  /R /D 
569        ModifyGraph rgb(fit_yAxisWave)=(0,0,0)
570// annotate graph, filtering out special cases of Guinier fits
571// Text Boxes must be used, since ControlBars on graphs DON'T print out
572       
573        // need access to Global wave, result of fit
574        //ystr and xstr are the axis strings - filter with a do-loop
575        String ystr="",xstr=""
576        //ControlInfo/W=FitPanel ywave
577        Wave xw = $("root:"+partialName+":"+partialName + "_q")
578        ControlInfo/W=FitPanel yModel
579        ystr = S_Value
580        ControlInfo/W=FitPanel xModel
581        xstr = S_Value
582       
583        WAVE W_coef=W_coef
584        WAVE W_sigma=W_sigma
585        String textstr_1,textstr_2,textstr_3 = ""
586        Variable rg,rgerr,minfit,maxfit,izerr
587       
588        textstr_1 = "Slope = " + num2str(W_coef[1]) + " ± " + num2str(W_sigma[1])
589        textstr_1 += "\rIntercept = " + num2str(W_coef[0]) + " ± " + num2str(W_sigma[0])
590        textstr_1 += "\rChi-Squared =  " + num2str(V_chisq/(V_npnts - 3))
591       
592        minfit = xw[xcsr(A)]
593        maxfit = xw[xcsr(B)]
594        textstr_2 = "Qmin =  " + num2str(minfit)
595        textstr_2 += "\rQmax =  " + num2str(maxfit)
596       
597        //model-specific calculations - I(0), Rg, etc.
598        //put these in textstr_3, at bottom
599        do
600                If (cmpstr("I",ystr) == 0)
601                        textstr_3 = "I(q=0) =  "  + num2str(W_coef[0]) +" ± "+num2str(W_sigma[0])
602                        break   
603                endif
604                If (cmpstr("ln(I)",ystr) == 0)
605                        izerr = abs(exp(W_coef[0]) - exp(W_coef[0]+W_sigma[0]))
606                        textstr_3 = "I(q=0) =  "  + num2str(exp(W_coef[0]))+" ± " + num2str(izerr)
607                        if(cmpstr("q^2",xstr) == 0)     //then a Guinier plot for a sphere (3-d)
608                                rg = sqrt(-3*W_coef[1])
609                                rgerr = 3*W_sigma[1]/(2*rg)
610                                textstr_3 += "\rRg (A) = " + num2str(rg) + " ± " + num2str(rgerr)
611                                textstr_3 += "\r" + num2str(rg*minfit) + " < Rg*q < " + num2str(rg*maxfit)
612                                break
613                        endif
614                        break   
615                endif
616                If (cmpstr("log(I)",ystr) == 0)
617                        if(cmpstr("log(q)",xstr) !=0 )  //extrapolation is nonsense
618                                textstr_3 = "I(q=0) =  "  + num2str(10^(W_coef[0]))
619                        endif
620                        break   
621                endif
622                If (cmpstr("1/I",ystr) == 0)
623                        izerr = abs(1/W_coef[0] - 1/(W_coef[0]+W_sigma[0]))
624                        textstr_3 = "I(q=0) =  "  + num2str(1/W_coef[0])+" ± " + num2str(izerr)
625                        break
626                endif
627                If (cmpstr("I^a",ystr) == 0)
628                        //nothing
629                        break
630                endif
631                If (cmpstr("Iq^a",ystr) == 0)
632                        //nothing
633                        break
634                endif
635                If (cmpstr("I^a q^b",ystr) == 0)
636                        //nothing
637                        break
638                endif
639                If (cmpstr("1/sqrt(I)",ystr) == 0)
640                        izerr = abs( (W_coef[0])^-2 - (W_coef[0]+W_sigma[0])^-2 )
641                        textstr_3 = "I(q=0) =  "  + num2str((W_coef[0])^-2)+" ± " + num2str(izerr)
642                        break
643                endif
644                If (cmpstr("ln(Iq)",ystr) == 0)
645                        //nothing
646                        if(cmpstr("q^2",xstr) == 0)     //then a x-sect Guinier plot for a rod (2-d)
647                                // rg now is NOT the radius of gyration, but the x-sect DIAMETER
648                                rg = 4*sqrt(-W_coef[1])
649                                rgerr = 8*W_sigma[1]/rg
650                                textstr_3 = "Rod diameter (A) = " + num2str(rg) + " ± " + num2str(rgerr)
651                                textstr_3 += "\r" + num2str(rg*minfit) + " < Rg*q < " + num2str(rg*maxfit)
652                                break
653                        endif
654                        break
655                endif
656                If (cmpstr("ln(Iq^2)",ystr) == 0)
657                        //nothing
658                        if(cmpstr("q^2",xstr) == 0)     //then a 1-d Guinier plot for a sheet
659                                // rg now is NOT the radius of gyration, but the thickness
660                                rg = sqrt(-12*W_coef[1])
661                                rgerr = 6*W_sigma[1]/(2*rg)
662                                textstr_3 = "Platelet thickness (A) = " + num2str(rg) + " ± " + num2str(rgerr)
663                                textstr_3 += "\r" + num2str(rg*minfit) + " < Rg*q < " + num2str(rg*maxfit)
664                                break
665                        endif
666                        break
667                endif
668               
669        while(0)
670        //kill the old textboxes, if they exist
671        TextBox/W=FitWindow/K/N=text_1
672        TextBox/W=FitWindow/K/N=text_2
673        TextBox/W=FitWindow/K/N=text_3
674        // write the new text boxes
675        TextBox/W=FitWindow/N=text_1/A=LT textstr_1
676        TextBox/W=FitWindow/N=text_2/A=LC textstr_2
677        If (cmpstr("",textstr_3) != 0)          //only display textstr_3 if it isn't null
678                TextBox/W=FitWindow/N=text_3/A=LB textstr_3
679        endif
680       
681        //adjust the plot range to reflect the actual fitted range
682        //cursors are already on the graph, done by Rescale_Data()
683        AdjustAxisToCursors()
684       
685End
686
687// adjusts both the x-axis scaling  and y-axis scaling to the cursor range
688// **cursors are already on the graph, done by Rescale_Data()
689//
690// will expand the scale to show an extra 5 points in each direction (if available)
691Function AdjustAxisToCursors()
692
693        DoWindow/F FitWindow
694        WAVE xAxisWave = root:xAxisWave
695        WAVE yAxisWave = root:yAxisWave
696        Variable xlow,xhigh,ylow,yhigh,yptlow,ypthigh
697        Variable extraPts = 5, num=numpnts(xAxisWave)
698       
699        String csrA = CsrInfo(A ,"FitWindow")
700        String csrB = CsrInfo(B ,"FitWindow")
701       
702        //x-levels, these are monotonic
703        Variable ptLow,ptHigh,tmp
704        ptLow = NumberByKey("POINT", csrA ,":" ,";")
705        ptHigh = NumberByKey("POINT", csrB ,":" ,";")
706        if(ptLow > ptHigh)
707                tmp= ptLow
708                ptLow=ptHigh
709                ptHigh=tmp
710        endif
711
712        // keep extended point range in bounds
713        ptLow = (ptLow-extraPts) >= 0 ? ptLow-extraPts : 0
714        ptHigh = (ptHigh+extraPts) <= (num-1) ? ptHigh + extraPts : num-1
715       
716        xlow = xAxisWave[ptLow]
717        xhigh = xAxisWave[ptHigh]
718//old way
719//      xlow = xAxisWave[xcsr(A)]
720//      xhigh = xAxisWave[xcsr(B)]
721//      if(xlow > xhigh)
722//              xhigh = xlow
723//              xlow = xAxisWave[xcsr(B)]
724//      endif
725       
726        //y-levels (old way)
727//      FindLevel/P/Q xAxisWave, xlow
728//      if(V_flag == 1)                 //level NOT found
729//              DoAlert 0,"Lower q-limit not in experimental q-range. Re-enter a better value"
730//      endif
731//      yptlow = V_LevelX
732//      FindLevel/P/Q xAxisWave, xhigh
733//      if(V_flag == 1)
734//              DoAlert 0,"Upper q-limit not in experimental q-range. Re-enter a better value"
735//      endif
736//      ypthigh = V_LevelX
737
738//      Print xlow,xhigh,yptlow,ypthigh
739//      Print yAxisWave[yptlow],yAxisWave[ypthigh]
740       
741
742        // make sure ylow/high are in the correct order, since the slope could be + or -
743        yhigh = max(yAxisWave[ptlow],yAxisWave[pthigh])
744        ylow = min(yAxisWave[ptlow],yAxisWave[pthigh])
745       
746//      Print ptLow,ptHigh
747//      print xlow,xhigh
748//      print ylow,yhigh
749       
750        SetAxis bottom,xlow,xhigh
751        SetAxis left ylow,yhigh
752       
753End
754
755///// procedures added from other SANS Reduction files
756//
757//
758
759//function called by the popups to get a file list of data that can be sorted
760// this procedure simply removes the raw data files from the string - there
761//can be lots of other junk present, but this is very fast...
762//
763// could also use the alternate procedure of keeping only file with the proper extension
764//
765// another possibility is to get a listing of the text files, but is unreliable on
766// Windows, where the data file must be .txt (and possibly OSX)
767//
768Function/S filterButtonProc(ctrlName)
769        String ctrlName
770
771        String newList=""
772//      String list="",newList="",item=""
773//      Variable num,ii
774//     
775//      //check for the path
776//      PathInfo catPathName
777//      if(V_Flag==0)
778//              DoAlert 0, "Data path does not exist - pick the data path from the button on the FIT panel"
779//              Return("")
780//      Endif
781//     
782//      list = IndexedFile(catpathName,-1,"????")
783//      num=ItemsInList(list,";")
784//      //print "num = ",num
785//      for(ii=(num-1);ii>=0;ii-=1)
786//              item = StringFromList(ii, list  ,";")
787//              //simply remove all that are not raw data files (SA1 SA2 SA3)
788//              if( !stringmatch(item,"*.SA1*") && !stringmatch(item,"*.SA2*") && !stringmatch(item,"*.SA3*") )
789//                      if( !stringmatch(item,".*") && !stringmatch(item,"*.pxp") && !stringmatch(item,"*.DIV"))                //eliminate mac "hidden" files, pxp, and div files
790//                              newlist += item + ";"
791//                      endif
792//              endif
793//      endfor
794//      //remove VAX version numbers
795//      newList = RemoveVersNumsFromList(newList)
796//      //sort
797//      newList = SortList(newList,";",0)
798
799// Jan 2013 -- replaced with a utility function that filters out raw, div, mask, etc.
800        newList = A_ReducedDataFileList("")
801       
802        return newlist
803End
804
805
806
807//////////////////////////////////////// FIT RPA ///////////////////////////////////////////
808//****************************************
809//procedures for creating and initializing the FITRPA panel
810//global variables (numerical only) are kept in root:myGlobals:FITRPA folder,
811//created as needed
812//
813// very similar in function to the FIT panel
814//
815Proc OpenFitRPAPanel()
816        If(WinType("FitRPAPanel") == 0)
817                //create the necessary data folder
818                NewDataFolder/O root:myGlobals:FITRPA
819                //initialize the values
820                Variable/G root:myGlobals:FITRPA:gLolim = 0.02
821                Variable/G root:myGlobals:FITRPA:gUplim = 0.04
822                Variable/G root:myGlobals:FITRPA:gBack = 0
823                Variable/G root:myGlobals:FITRPA:gLambda = 6.0
824                PathInfo/S catPathName
825                String localpath = S_path
826                if (V_flag == 0)
827                //path does not exist - no folder selected
828                        String/G root:myGlobals:FITRPA:gPathStr = "no folder selected"
829                else
830                        String/G root:myGlobals:FITRPA:gPathStr = localpath
831                endif
832                String/G    root:myGlobals:FITRPA:gDataPopList = "none"
833                FitRPAPanel()
834        else
835                //window already exists, just bring to front for update
836                DoWindow/F FitRPAPanel
837        endif
838        //pop the menu
839        FilePopMenuProc("",1,"")
840End
841
842//used on the fit/rpa panel to select the path for the data
843// - automatically pops the file list after the new  path selection
844Function FITRPAPickPathButton(ctrlName) : ButtonControl
845        String ctrlName
846
847        Variable err = A_PickPath()             //sets global path value
848        SVAR pathStr = root:myGlobals:gCatPathStr
849       
850        //set the global string for NSORT to the selected pathname
851        String/G root:myGlobals:FITRPA:gPathStr = pathStr
852       
853        //call the popup menu proc's to re-set the menu choices
854        FilePopMenuProc("filePopup",1,"")
855       
856End
857
858//gets a valid file list (simply not the files with ".SAn" in the name)
859//
860Function FilePopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
861        String ctrlName
862        Variable popNum
863        String popStr
864
865        String tempStr=ReducedDataFileList(ctrlName)
866        if(strlen(tempStr)==0)
867                tempStr = "Pick the data path"
868        Endif
869        String/G root:myGlobals:FITRPA:gDataPopList =   tempStr //function is in NSORT.ipf
870        ControlUpdate filePopup
871       
872End
873
874
875
876// window recreation macro to draw the fit/rpa panel
877//globals and data folders must be present before drawing panel
878//
879Window FitRPAPanel()
880
881        String angst = root:Packages:NIST:gAngstStr
882        PauseUpdate; Silent 1           // building window...
883        NewPanel /W=(250,266,591,579)/K=1
884        ModifyPanel cbRGB=(32768,54528,65280)
885        ModifyPanel fixedSize=1
886        SetDrawLayer UserBack
887        SetDrawEnv fstyle= 1
888        DrawText 81,19,"Select Experimental Data"
889        SetDrawEnv fstyle= 1
890        DrawText 97,102,"q-range to fit ("+angst+"^-1)"
891        SetDrawEnv fstyle= 1
892        DrawText 87,239,"Select the fit parameters"
893        SetDrawEnv fillpat= 0
894        DrawRect 1,103,338,224
895        SetDrawEnv fillpat= 0
896        DrawRect 1,20,337,83
897        SetDrawEnv fillpat= 0
898        DrawRect 2,241,337,275
899//      Button PathButton,pos={6,26},size={80,20},proc=FitRPAPickPathButton,title="Pick Path"
900//      Button PathButton,help={"Select the local path to the folder containing your SANS data"}
901//      SetVariable setPath,pos={95,29},size={240,17},title="Path:"
902//      SetVariable setPath,help={"The current path to the local folder with SANS data"}
903//      SetVariable setPath,fSize=10
904//      SetVariable setPath,limits={0,0,0},value= root:myGlobals:FITRPA:gPathStr
905        PopupMenu filePopup,pos={8,30},size={96,21},proc=FilePopMenuProc,title="Files"
906        PopupMenu filePopup,help={"Select the data file to load."}
907        PopupMenu filePopup,mode=5,popvalue="none",value= #"root:myGlobals:FITRPA:gDataPopList"
908        SetVariable lambda,pos={111,250},size={120,18},title="Lambda ("+angst+")"
909        SetVariable lambda,help={"This sets the wavelength for the multiple scattering corrections."}
910        SetVariable lambda,limits={0,10,0},value= root:myGlobals:FITRPA:gLambda
911        Button GoFit,pos={60,286},size={80,20},proc=DoFITRPA,title="Do the Fit"
912        Button GoFit,help={"This button will do the specified fit using the selections in this panel"}
913        SetVariable lolim,pos={82,113},size={134,28},title="Lower Limit"
914        SetVariable lolim,help={"Enter the lower q-limit to perform the fit ("+angst+"^-1)"}
915        SetVariable lolim,limits={0,5,0},value= root:myGlobals:FITRPA:gLolim
916        SetVariable uplim,pos={80,140},size={134,28},title="Upper Limit"
917        SetVariable uplim,help={"Enter the upper q-limit to perform the fit ("+angst+"^-1)"}
918        SetVariable uplim,limits={0,5,0},value= root:myGlobals:FITRPA:gUplim
919        CheckBox RPA_check0,pos={64,198},size={190,20},title="Use cursor range from FitWindow"
920        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
921        PopupMenu model,pos={3,249},size={101,21},title="Standard"
922        PopupMenu model,help={"This popup selects which standard should be used to fit this data"}
923        PopupMenu model,mode=1,popvalue="B",value= #"\"B;C;AS\""
924        Button sh_all,pos={82,168},size={130,20},proc=ShowAllButtonProc,title="Show Full q-range"
925        Button sh_all,help={"Use this to show the entire q-range of the data rather than just the fitted range."}
926        Button loadButton,pos={20,55},size={70,20},proc=FITRPA_Load_Proc,title="Load File"
927        Button loadButton,help={"After choosing a file, load it into memory and plot it with this button."}
928        Button helpButton,pos={270,55},size={25,20},proc=showFITHelp,title="?"
929        Button helpButton,help={"Show help file for RPA fitting"}
930        Button DoneButton,pos={200,286},size={50,20},proc=FITRPADoneButton,title="Done"
931        Button DoneButton,help={"This button will close the panel and the associated graph"}
932EndMacro
933
934
935Proc FITRPADoneButton(ctrlName) : ButtonControl
936        String ctrlName
937        DoWindow/K FitWindow
938        DoWindow/K FitRPAPanel
939end
940
941//dispatches the fit to the appropriate model
942//and the appropriate range, based on selections in the panel
943//
944Proc DoFITRPA(ctrlName) : ButtonControl
945        String ctrlName
946        //
947        String cleanLastFileName = CleanupName(root:Packages:NIST:gLastFileName,0)
948        String tmpStr = "root:"+cleanLastFileName+":"+cleanLastFileName
949
950        Duplicate/O $(tmpStr+"_q") xAxisWave
951        Duplicate/O $(tmpStr+"_i") yAxisWave
952        Duplicate/O $(tmpStr+"_s") yErrWave,yWtWave,residWave
953
954        yWtWave = 1/yErrWave
955       
956        String xlabel = "q (A^-1)"
957        String ylabel = "Intensity"
958        //Check to see if the FitWindow exists
959        //Plot the data in a FitWindow
960        If(WinType("FitWindow") == 0)
961                Display /W=(5,42,480,400)/K=1  yAxisWave vs xAxisWave
962                ModifyGraph mode=3,standoff=0,marker=8
963                ErrorBars/T=0 yAxisWave Y,wave=(yErrWave,yErrWave)
964                DoWindow/C FitWindow
965                ShowInfo
966        else
967                //window already exists, just bring to front for update
968                DoWindow/F FitWindow
969                // remove old text boxes
970                TextBox/K/N=text_1
971                TextBox/K/N=text_2
972                TextBox/K/N=text_3
973        endif
974       
975        //see if the user wants to use the data specified by the cursors - else use numerical values
976        Variable xlow,xhigh,ylow,yhigh,yes_cursors
977        ControlInfo/W=FitRPAPanel RPA_check0            //V_value = 1 if it is checked, meaning yes, use cursors
978        yes_cursors = V_value
979
980        ControlInfo/W=FitRPAPanel lolim
981        xlow = V_value
982        ControlInfo/W=FitRPAPanel uplim
983        xhigh = V_value
984        if(yes_cursors)
985                xlow = xAxisWave[xcsr(A)]
986                xhigh = xAxisWave[xcsr(B)]
987                if(xlow > xhigh)
988                        xhigh = xlow
989                        xlow = xAxisWave[xcsr(B)]
990                endif
991//              Print "xlow,xhigh = ",xlow,xhigh
992                ylow = yAxisWave[xcsr(A)]
993                yhigh = yAxisWave[xcsr(B)]
994                if(ylow > yhigh)
995                        ylow=yhigh
996                        yhigh = yAxisWave[xcsr(A)]
997                endif
998        else
999                FindLevel/P/Q xAxisWave, xlow
1000                if(V_flag == 1)                 //level NOT found
1001                        DoAlert 0,"Lower q-limit not in experimental q-range. Re-enter a better value"
1002                        DoWindow/K FitWindow
1003                        Abort
1004                endif
1005                Cursor/P A, yAxisWave,trunc(V_LevelX)+1
1006                ylow = yAxisWave[V_LevelX]
1007                FindLevel/P/Q xAxisWave, xhigh
1008                if(V_flag == 1)
1009                        DoAlert 0,"Upper q-limit not in experimental q-range. Re-enter a better value"
1010                        DoWindow/K FitWindow
1011                        Abort
1012                endif
1013                Cursor/P B, yAxisWave,trunc(V_LevelX)
1014                yhigh = yAxisWave[V_LevelX]
1015                if(ylow > yhigh)
1016                        yhigh=ylow
1017                        ylow = yAxisWave[V_levelX]
1018                endif
1019        endif   //if(V_value)
1020        SetAxis bottom,xlow,xhigh
1021       
1022//      print "ylow,yhigh",ylow,yhigh
1023       
1024        //Get the rest of the data from the panel
1025        //such as which standard, the wavelength
1026        ControlInfo/W=FitRPAPanel model
1027
1028        //find the model name
1029        String modelName = S_value
1030       
1031        Variable first_guess, seglength,iabs,iarb,thick
1032        Make/D/O/N=2 fitParams
1033       
1034        seglength = 6.8
1035       
1036        first_guess = 1.0
1037        fitParams[0] = first_guess
1038        fitParams[1] = seglength
1039
1040        If (cmpstr(modelName,"B")==0)
1041                iabs = BStandardFunction(fitParams,xlow)
1042                fitParams[0] = yhigh/iabs
1043//              Print fitParams[0],fitParams[1]
1044                FuncFit BStandardFunction fitParams yAxisWave(xcsr(A),xcsr(B)) /X=xAxisWave /W=yWtWave /D
1045                iarb = BStandardFunction(fitParams, 0.0)
1046                iabs = iarb/fitParams[0]
1047                thick = 0.153
1048        endif
1049        If (cmpstr(modelName,"C")==0)
1050                iabs = CStandardFunction(fitParams,xlow)
1051                fitParams[0] = yhigh/iabs
1052                FuncFit CStandardFunction fitParams yAxisWave(xcsr(A),xcsr(B)) /X=xAxisWave /W=yWtWave /D
1053                iarb = CStandardFunction(fitParams, 0.0)
1054                iabs = iarb/fitParams[0]
1055                thick= 0.153
1056        endif
1057        If (cmpstr(modelName,"AS")==0)
1058                iabs = ASStandardFunction(fitParams,xlow)
1059                fitParams[0] = yhigh/iabs
1060                FuncFit ASStandardFunction fitParams yAxisWave(xcsr(A),xcsr(B)) /X=xAxisWave /W=yWtWave /D
1061                iarb = ASStandardFunction(fitParams, 0.0)
1062                iabs = iarb/fitParams[0]
1063                thick = 0.1
1064        endif
1065        ModifyGraph rgb(fit_yAxisWave)=(0,0,0)
1066        Label left ylabel
1067        Label bottom xlabel     //E denotes "scaling"  - may want to use "units" instead       
1068
1069        ControlInfo/W=FitRPAPanel lambda
1070       
1071        Variable cor_mult = 1.0 + 2.2e-4*V_Value^2
1072       
1073        //WAVE W_coef=W_coef
1074        //WAVE W_sigma=W_sigma
1075        String textstr_1,textstr_2,textstr_3 = ""
1076        textstr_1 = "Scaling Parameter: "+num2str(fitParams[0])+" ± "+num2str(W_sigma[0])
1077        textstr_1 += "\rSegment Length: "+num2str(fitParams[1])+" ± "+num2str(W_sigma[1])
1078        textstr_1 += "\rChi-Squared =  " + num2str(V_chisq/(V_npnts - 3))
1079       
1080        textstr_2 = "Cross section at q=0:  Iabs(0) = "+num2str(iabs)+"cm\S-1\M"
1081        textstr_2 += "\rData extrapolated to q=0: Im(0) = "+num2str(iarb)+" Counts/(10\S8\M  Mon cts)"
1082        textstr_2 += "\rData corrected for multiple scattering: I(0) = "+num2str(iarb/cor_mult)+" Counts/(10\S8\M  Mon cnts)"
1083       
1084        textstr_3 = "In the ABS protocol, "
1085        textstr_3 += "\rStandard Thickness, d = "+num2str(thick)+"cm"
1086        textstr_3 += "\rI(0), Iarb(0) = "+num2str(iarb/cor_mult)+"Counts/(10\S8\M Mon cts)"
1087        textstr_3 += "\rStandard Cross Section, Iabs(0) = "+num2str(iabs)+"cm\S-1\M"
1088        TextBox/K/N=text_1
1089        TextBox/K/N=text_2
1090        TextBox/K/N=text_3
1091        TextBox/N=text_2/A=RT textstr_2
1092        TextBox/N=text_3/A=RC textstr_3
1093        TextBox/N=text_1/A=RB textstr_1
1094       
1095End
1096
1097//loads the file selected in the popup for fitting with POL
1098//standard functions. Reads the wavelength from the header, using
1099//6 A as the default
1100//plots the data in FitWindow after reading the file
1101//updates lambda and full q-range  on the Panel
1102//
1103Proc FITRPA_Load_Proc(ctrlName): ButtonControl
1104        String ctrlName
1105        //Load the data
1106        String tempName="",partialName=""
1107        Variable err
1108        ControlInfo $"filePopup"
1109        //find the file from the partial filename
1110        If( (cmpstr(S_value,"")==0) || (cmpstr(S_value,"none")==0) )
1111                //null selection, or "none" from any popup
1112                Abort "no file selected in popup menu"
1113        else
1114                //selection not null
1115                partialName = S_value
1116                //Print partialName
1117        Endif
1118        //get a valid file based on this partialName and catPathName
1119        tempName = FindValidFilename(partialName)
1120
1121        Variable lambdaFromFile=GetLambdaFromReducedData(tempName)
1122        Variable/G root:myGlobals:FITRPA:gLambda = lambdaFromFile
1123        Print "Lambda in file read as:", lambdaFromFile
1124       
1125        //prepend path to tempName for read routine
1126        PathInfo catPathName
1127        tempName = S_path + tempName
1128       
1129        //load in the data (into the root directory)
1130        LoadOneDDataWithName(tempName,0)
1131        //Print S_fileName
1132        //Print tempName
1133       
1134        String cleanLastFileName = CleanupName(root:Packages:NIST:gLastFileName,0)
1135        String tmpStr = "root:"+cleanLastFileName+":"+cleanLastFileName
1136
1137        Duplicate/o $(tmpStr+"_q") xAxisWave
1138        Duplicate/o $(tmpStr+"_i") yAxisWave
1139        Duplicate/o $(tmpStr+"_s") yErrWave
1140       
1141        Variable xmin, xmax
1142        WaveStats/Q xAxisWave
1143        root:myGlobals:FITRPA:gLolim=V_min
1144        root:myGlobals:FITRPA:gUplim=V_max
1145        ControlUpdate/W=FITRPAPanel/A
1146       
1147        //Check to see if the FitWindow exists
1148        //Plot the data in a FitWindow
1149        If(WinType("FitWindow") == 0)
1150                Display /W=(5,42,480,400)/K=1  yAxisWave vs xAxisWave
1151                ModifyGraph mode=3,standoff=0,marker=8
1152                ErrorBars/T=0 yAxisWave Y,wave=(yErrWave,yErrWave)
1153                TextBox/C/N=textLabel/A=RB "File = "+cleanLastFileName
1154                DoWindow/C FitWindow
1155                ShowInfo
1156        else
1157                //window already exists, just bring to front for update
1158                DoWindow/F FitWindow
1159                TextBox/C/N=textLabel/A=RB "File = "+cleanLastFileName
1160        endif
1161        // remove old text boxes
1162        TextBox/K/N=text_1
1163        TextBox/K/N=text_2
1164        TextBox/K/N=text_3
1165        RemoveFromGraph/W=fitWindow /Z fit_yAxisWave
1166        SetAxis/A
1167       
1168        //put cursors on the graph at first and last points
1169        Cursor/P A  yAxisWave  0
1170        Cursor/P B yAxisWave (numpnts(yAxisWave) - 1)
1171End
1172
1173//Fitting function for the POL-B standards
1174//
1175Function BStandardFunction(parameterWave, x)
1176        Wave parameterWave; Variable x
1177       
1178        //Model parameters
1179        Variable KN=4.114E-3,CH=9.613E4, CD=7.558E4, NH=1872, ND=1556
1180        Variable INC=0.32, CHIV=2.2E-6
1181        //Correction based on absolute flux measured 5/93
1182        Variable CORR = 1.1445
1183       
1184        //Local variables
1185        Variable AP2,QRGH,QRGD,IABS_RPA,IABS
1186       
1187        //Calculate the function here
1188        ap2=parameterWave[1]^2
1189        qrgh = x*sqrt(nh*ap2/6)
1190        qrgd = x*sqrt(nd*ap2/6)
1191        iabs_rpa = kn/(1/(ch*FIT_dbf(qrgh)) + 1/(cd*FIT_dbf(qrgd)) - chiv)
1192        iabs = corr*iabs_rpa + inc
1193       
1194        //return the result
1195        return parameterWave[0]*iabs
1196       
1197End
1198
1199//Fitting function for the POL-C standards
1200//
1201Function CStandardFunction(parameterWave, x)
1202        Wave parameterWave; Variable x
1203       
1204        //Model parameters
1205        Variable KN=4.114E-3,CH=2.564E5, CD=1.912E5, NH=4993, ND=3937
1206        Variable INC=0.32, CHIV=2.2E-6
1207        //Correction based on absolute flux measured 5/93
1208        Variable CORR = 1.0944
1209       
1210        //Local variables
1211        Variable AP2,QRGH,QRGD,IABS_RPA,IABS
1212       
1213        //Calculate the function here
1214        ap2=parameterWave[1]^2
1215        qrgh = x*sqrt(nh*ap2/6)
1216        qrgd = x*sqrt(nd*ap2/6)
1217        iabs_rpa = kn/(1/(ch*FIT_dbf(qrgh)) + 1/(cd*FIT_dbf(qrgd)) - chiv)
1218        iabs = corr*iabs_rpa + inc
1219       
1220        //return the result
1221        return parameterWave[0]*iabs
1222       
1223End
1224
1225//fitting function for the POL-AS standards
1226//
1227Function ASStandardFunction(parameterWave, x)
1228        Wave parameterWave; Variable x
1229       
1230        //Model parameters
1231        Variable KN=64.5,CH=1.0, CD=1.0, NH=766, ND=766
1232        Variable INC=0.32, CHIV=0.0
1233       
1234        //Local variables
1235        Variable AP2,QRGH,QRGD,IABS_RPA,IABS
1236       
1237        //Calculate the function here
1238        ap2=parameterWave[1]^2
1239        qrgh = x*sqrt(nh*ap2/6)
1240
1241//The following lines were commented out in the fortran function
1242        //qrgd = x*sqrt(nd*ap2/6)
1243        //iabs_rpa = kn/(1/(ch*FIT_dbf(qrgh)) + 1/(cd*FIT_dbf(qrgd)) - chiv)
1244
1245        iabs_rpa = kn*FIT_dbf(qrgh)
1246        iabs = iabs_rpa + inc
1247       
1248        //return the result
1249        return parameterWave[0]*iabs
1250       
1251End
1252
1253//Debye Function used for polymer standards
1254Function FIT_dbf(rgq)
1255        Variable rgq
1256        Variable x
1257       
1258        x=rgq*rgq
1259        if (x < 5.0E-3)
1260                return 1.0 - x/3 + x^2/12
1261        else
1262                return 2*(exp(-x) + x - 1)/x^2
1263        endif
1264End
1265
1266
1267//////////////////////////////// EMD FIT RPA //////////////////////////////////////
1268
1269
1270
1271
1272
1273
1274
1275
1276//procedures to clean up after itself
1277//
1278// -- note that it's never going to unload if the SANS Reduction is open too - since
1279// the old FIT_Ops was always loaded, and now points to this file.
1280//
1281Function UnloadLinFit()
1282
1283        if (WinType("FitPanel") == 7)
1284                DoWindow/K FitPanel
1285        endif
1286        if (WinType("FitWindow") != 0)
1287                DoWindow/K $"FitWindow"
1288        endif
1289        SetDataFolder root:
1290        Killwaves/Z xAxisWave,yAxisWave,yErrWave,residWave,yWtWave,fit_yAxisWave
1291       
1292        SVAR/Z fileVerExt=root:Packages:NIST:SANS_ANA_EXTENSION
1293        if(SVAR_Exists(fileVerExt) == 0)
1294                return 0
1295        endif
1296       
1297        String fname="LinearizedFits"
1298        Execute/P "DELETEINCLUDE \""+fname+fileVerExt+"\""
1299        Execute/P "COMPILEPROCEDURES "
1300end
1301
1302#if(exists("root:Packages:NIST:SANS_ANA_EXTENSION") != 0)
1303//this keeps the SANS Models menu from appearing in the SANS Reduction package
1304Menu "SANS Models"
1305        Submenu "Packages"
1306                "Unload Linear Fitting", UnloadLinFit()
1307        End
1308end
1309
1310#endif
1311
1312Function FIT_PickPathButtonProc(ctrlName) : ButtonControl
1313        String ctrlName
1314
1315        A_PickPath()
1316        //pop the file menu
1317        FIT_FilePopMenuProc("",1,"")
1318End
Note: See TracBrowser for help on using the repository browser.