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

Last change on this file since 570 was 570, checked in by srkline, 13 years ago

Change (1):
In preparation for release, updated pragma IgorVersion?=6.1 in all procedures

Change (2):
As a side benefit of requiring 6.1, we can use the MultiThread? keyword to thread any model function we like. The speed benefit is only noticeable on functions that require at least one integration and at least 100 points (resolution smearing is NOT threaded, too many threadSafe issues, too little benefit). I have chosen to use the MultiThread? only on the XOP assignment. In the Igor code there are too many functions that are not explicitly declared threadsafe, making for a mess.

File size: 25.0 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//
23///////////////////////////////
24
25//main procedures to open the panel, initializing the data folder and global variables
26//as necessary. All are kept in a :FIT subfolder to avoid overlap with other variables
27//
28// To use any of the fit functions in the FIT panel, I(Q) data must already
29// be loaded into memory (using "plot" from the 1-D data operations
30// ** this may be useful to change in the future, replacing the 3 popups
31// with a list box - allowing the user to pick/load the data from the fit panel
32// and not offering any choice of q/i/s waves to use. (more consistent with the operation
33// of the FIT/RPA panel)
34//
35Proc A_OpenFitPanel()
36        If(WinType("A_FitPanel") == 0)
37                //create the necessary data folder
38                NewDataFolder/O root:Packages
39                NewDataFolder/O root:Packages:NIST
40                NewDataFolder/O root:Packages:NIST:FIT
41                //initialize the values
42                Variable/G root:Packages:NIST:FIT:gLolim = 0.02
43                Variable/G root:Packages:NIST:FIT:gUplim = 0.04
44                Variable/G root:Packages:NIST:FIT:gExpA = 1
45                Variable/G root:Packages:NIST:FIT:gExpB = 1
46                Variable/G root:Packages:NIST:FIT:gExpC = 1
47                Variable/G root:Packages:NIST:FIT:gBack = 0
48                String/G root:Packages:NIST:FIT:gDataPopList = "none"
49                A_FitPanel()
50        else
51                //window already exists, just bring to front for update
52                DoWindow/F A_FitPanel
53                CheckBox check0,value=0         //deselect the checkbox to use cursors
54        endif
55        //pop the file menu
56        A_FIT_FilePopMenuProc("",1,"")
57End
58
59//the actual window recreation macro to draw the fit panel. Globals and data folder must
60// already be initialized
61Window A_FitPanel()
62        //String angst = root:Packages:NIST:gAngstStr
63        String angst = "A"
64        PauseUpdate; Silent 1           // building window...
65        NewPanel /W=(461,46,735,455)/K=1
66        ModifyPanel cbRGB=(32768,54615,65535), fixedSize=1
67        SetDrawLayer UserBack
68        DrawText 56,20,"Select Experimental Data"
69        DrawText 66,138,"q-range to fit ("+angst+"^-1)"
70        DrawText 42,268,"Select the y and x-axis scaling"
71        DrawLine 1,21,271,21
72        DrawLine -1,272,273,272
73        DrawLine -1,140,272,140
74        PopupMenu ywave,pos={13,60},size={154,19},title="Data File"
75        PopupMenu ywave,help={"Select the experimental intensity values"}
76        PopupMenu ywave,mode=1,value=root:Packages:NIST:FIT:gDataPopList,proc=A_FIT_FilePopMenuProc
77        Button loadButton,pos={13,92},size={130,20},proc=A_FIT_Load_Proc,title="Load and Plot File"
78        Button loadButton,help={"After choosing a file, load it into memory and plot it with this button."}
79        Button helpButton,pos={237,28},size={25,20},proc=A_showFITHelp,title="?"
80        Button helpButton,help={"Show help file for linearized fitting"}
81        PopupMenu ymodel,pos={20,281},size={76,19},title="y-axis"
82        PopupMenu ymodel,help={"This popup selects how the y-axis will be linearized based on the chosen data"}
83        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)\""
84        Button GoFit,pos={60,367},size={70,20},proc=A_DispatchModel,title="Do the Fit"
85        Button GoFit,help={"This button will do the specified fit using the selections in this panel"}
86        Button DoneButton,pos={180,367},size={50,20},proc=A_FITDoneButton,title="Done"
87        Button DoneButton,help={"This button will close the panel and the associated graph"}
88        SetVariable lolim,pos={64,147},size={134,17},title="Lower Limit"
89        SetVariable lolim,help={"Enter the lower q-limit to perform the fit ("+angst+"^-1)"}
90        SetVariable lolim,limits={0,5,0},value= root:Packages:NIST:FIT:gLolim
91        SetVariable uplim,pos={63,169},size={134,17},title="Upper Limit"
92        SetVariable uplim,help={"Enter the upper q-limit to perform the fit ("+angst+"^-1)"}
93        SetVariable uplim,limits={0,5,0},value= root:Packages:NIST:FIT:gUplim
94        SetVariable expa,pos={13,311},size={80,17},title="pow \"a\""
95        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"}
96        SetVariable expa,limits={-2,10,0},value= root:Packages:NIST:FIT:gExpA
97        SetVariable expb,pos={98,311},size={80,17},title="pow \"b\""
98        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"}
99        SetVariable expb,limits={0,10,0},value= root:Packages:NIST:FIT:gExpB
100        PopupMenu xmodel,pos={155,280},size={79,19},title="x-axis"
101        PopupMenu xmodel,help={"This popup selects how the x-axis will be linearized given the chosen data"}
102        PopupMenu xmodel,mode=1,value= #"\"q;log(q);q^2;q^c\""
103        CheckBox check0,pos={18,223},size={240,20},title="Use cursor range from FitWindow"
104        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
105        SetVariable back,pos={70,338},size={139,17},title="background"
106        SetVariable back,help={"This constant background value will be subtracted from the experimental intensity before fitting is done"}
107        SetVariable back,limits={-Inf,Inf,0},value= root:Packages:NIST:FIT:gBack
108        SetVariable expc,pos={182,310},size={80,17},title="pow \"c\""
109        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"}
110        SetVariable expc,limits={-10,10,0},value= root:Packages:NIST:FIT:gExpC
111        Button sh_all,pos={65,193},size={130,20},proc=A_ShowAllButtonProc,title="Show Full q-range"
112        Button sh_all,help={"Use this to show the entire q-range of the data rather than just the fitted range."}
113       
114        Button FIT_PathButton,pos={10,28},size={80,20},proc=A_FIT_PickPathButtonProc,title="Pick Path"
115
116EndMacro
117
118
119Proc A_FITDoneButton(ctrlName): ButtonControl
120        String ctrlName
121        DoWindow/K A_FitWindow
122        DoWindow/K A_FitPanel
123end
124
125Proc A_showFITHelp(ctrlName): ButtonControl
126        String ctrlName
127        DisplayHelpTopic/Z/K=1 "Linearized Fits"
128        if(V_flag != 0)
129                DoAlert 0, "The Linearized Fit Help file can not be found"
130        endif
131end
132
133//Loads the selected file for fitting
134//graphs the data as needed
135Proc A_FIT_Load_Proc(ctrlName): ButtonControl
136        String ctrlName
137       
138        //Load the data
139        String tempName="",partialName=""
140        Variable err
141        ControlInfo $"ywave"
142        //find the file from the partial filename
143        If( (cmpstr(S_value,"")==0) || (cmpstr(S_value,"none")==0) )
144                //null selection, or "none" from any popup
145                Abort "no file selected in popup menu"
146        else
147                //selection not null
148                partialName = S_value
149        Endif
150        //get a valid file based on this partialName and catPathName
151        tempName = A_FindValidFilename(partialName)
152
153        //prepend path to tempName for read routine
154        PathInfo catPathName
155       
156        tempName = S_path + tempName
157       
158        //load in the data (into the root directory)
159        A_LoadOneDDataWithName(tempName,0)              //let A_Rescale_Data() do the plotting
160        //Print S_fileName
161        //Print tempName
162       
163        String cleanLastFileName = CleanupName(partialName,0)
164        String dataStr = "root:"+cleanLastFileName+":"
165        tempName=dataStr + cleanLastFileName+"_q"
166        Duplicate/O $tempName xAxisWave
167        tempName=dataStr + cleanLastFileName+"_i"
168        Duplicate/O $tempName yAxisWave
169        tempName=dataStr + cleanLastFileName+"_s"
170        Duplicate/O $tempName yErrWave
171
172        //Plot, and adjust the scaling to match the axis scaling set by the popups
173        A_Rescale_Data(dataStr)
174       
175End
176
177//gets a valid file list (simply not the files with ".SAn" in the name)
178//
179Function A_FIT_FilePopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
180        String ctrlName
181        Variable popNum
182        String popStr
183       
184        String tempStr=A_filterButtonProc(ctrlName)
185        if(strlen(tempStr)==0)
186                tempStr = "Pick the data path"
187        Endif
188        String/G root:Packages:NIST:FIT:gDataPopList =tempStr
189        ControlUpdate ywave
190       
191End
192
193//direct porting of the fit program from the VAX, with no corrections and only
194//minor modifications of additional  linearizations and the option
195//to subtract a constant (q-independent) background value before doing any
196//of the fits. The original data on disk (and as loaded) is never modified, all
197//manipulation is done from a copy of the data.
198
199//button procedure to show the entire axis range of the data, rather than just
200//the fitted range, which is the default display after a fit is performed
201//
202Function A_ShowAllButtonProc(ctrlName) : ButtonControl
203        String ctrlName
204
205        //bring the FitWindow to the front and Autoscale the axes
206        DoWindow/F A_FitWindow
207        SetAxis/A
208End
209
210// function that takes the current dataset (already loaded)
211// and replots it based on the X/Y axis scaling selected in the popups
212// (does not fit the data)
213//
214// dataStr is the root:folder: of the data that was loaded
215Function A_Rescale_Data(dataStr)
216        String dataStr
217       
218        //Scaling exponents and background value
219        Variable pow_a,pow_b,pow_c,bkg
220        ControlInfo/W=A_FitPanel expa
221        pow_a = V_value
222        ControlInfo/W=A_FitPanel expb
223        pow_b = V_value
224        ControlInfo/W=A_FitPanel expc
225        pow_c = V_value
226        ControlInfo/W=A_FitPanel back
227        bkg = V_value
228       
229//check for physical limits on exponent values
230// if bad values found, alert, and reset to good values so the rescaling can continue
231        NVAR gA = root:Packages:NIST:FIT:gExpA
232        NVAR gB = root:Packages:NIST:FIT:gExpB
233        NVAR gC = root:Packages:NIST:FIT:gExpC
234        if((pow_a < -2) || (pow_a > 10))
235                DoAlert 0,"Exponent a must be in the range (-2,10) - the exponent a has been reset to 1"
236                gA = 1
237        endif
238        if((pow_b < 0) || (pow_b > 10))
239                DoAlert 0,"Exponent b must be in the range (0,10) - the exponent b has been reset to 1"
240                gB = 1
241        endif
242        //if q^c is the x-scaling, c must be be within limits and also non-zero
243        ControlInfo/W=A_FitPanel xModel
244        If (cmpstr("q^c",S_Value) == 0)
245                if(pow_c == 0)
246                        DoAlert 0,"Exponent c must be non-zero, c has been reset to 1"
247                        gC = 1
248                endif
249                if((pow_c < -10) || (pow_c > 10))
250                        DoAlert 0,"Exponent c must be in the range (-10,10), c has been reset to 1"
251                        gC = 1
252                endif
253        endif
254       
255        //do the rescaling of the data
256        // get the current experimental q, I, and std dev. waves (as they would be loaded )
257        String baseStr = ParseFilePath(0,dataStr,":",1,0)               //give me the last part of the path
258       
259        Wave xw = $(dataStr+baseStr+"_q")
260        Wave yw = $(dataStr+baseStr+"_i")
261        Wave ew = $(dataStr+baseStr+"_s")
262       
263        //variables set for each model to control look of graph
264        Variable xlow,xhigh,ylow,yhigh,yes_cursors
265        String xlabel,ylabel,xstr,ystr
266        //check for proper y-scaling selection, make the necessary waves
267        ControlInfo/W=A_FitPanel yModel
268        ystr = S_Value
269//      print "ystr = ",ystr
270        do
271                // make the new yaxis waves, including weighting wave
272                Duplicate/O yw yAxisWave,yErrWave,yWtWave,residWave
273                //subtract the background value from yAxisWave before doing any rescaling
274                yAxisWave = yw - bkg
275               
276                If (cmpstr("I",S_Value) == 0)
277                        SetScale d 0,0,"1/cm",yAxisWave
278                        yErrWave = ew
279                        yWtWave = 1/yErrWave
280                        yAxisWave = yAxisWave
281                        ylabel = "I(q)"
282                        break   
283                endif
284                If (cmpstr("ln(I)",S_Value) == 0)
285                        SetScale d 0,0,"",yAxisWave
286                        yErrWave = ew/yAxisWave
287                        yWtWave = 1/yErrWave
288                        yAxisWave = ln(yAxisWave)
289                        ylabel = "ln(I)"
290                        break   
291                endif
292                If (cmpstr("log(I)",S_Value) == 0)
293                        SetScale d 0,0,"",yAxisWave
294                        yErrWave = ew/(2.30*yAxisWave)
295                        yWtWave = 1/yErrWave
296                        yAxisWave = log(yAxisWave)
297                        ylabel = "log(I)"
298                        break   
299                endif
300                If (cmpstr("1/I",S_Value) == 0)
301                        SetScale d 0,0,"",yAxisWave
302                        yErrWave = ew/yAxisWave^2
303                        yWtWave = 1/yErrWave
304                        yAxisWave = 1/yAxisWave
305                        ylabel = "1/I"
306                        break
307                endif
308                If (cmpstr("I^a",S_Value) == 0)
309                        SetScale d 0,0,"",yAxisWave
310                        yErrWave = ew*abs(pow_a*(yAxisWave^(pow_a-1)))
311                        yWtWave = 1/yErrWave
312                        yAxisWave = yAxisWave^pow_a
313                        ylabel = "I^"+num2str(pow_a)
314                        break
315                endif
316                If (cmpstr("Iq^a",S_Value) == 0)
317                        SetScale d 0,0,"",yAxisWave
318                        yErrWave = ew*xw^pow_a
319                        yWtWave = 1/yErrWave
320                        yAxisWave = yAxisWave*xw^pow_a
321                        ylabel = "I*q^"+num2str(pow_a)
322                        break
323                endif
324                If (cmpstr("I^a q^b",S_Value) == 0)
325                        SetScale d 0,0,"",yAxisWave
326                        yErrWave = ew*abs(pow_a*(yAxisWave^(pow_a-1)))*xw^pow_b
327                        yWtWave = 1/yErrWave
328                        yAxisWave = yAxisWave^pow_a*xw^pow_b
329                        ylabel = "I^" + num2str(pow_a) + "q^"+num2str(pow_b)
330                        break
331                endif
332                If (cmpstr("1/sqrt(I)",S_Value) == 0)
333                        SetScale d 0,0,"",yAxisWave
334                        yErrWave = 0.5*ew*yAxisWave^(-1.5)
335                        yWtWave = 1/yErrWave
336                        yAxisWave = 1/sqrt(yAxisWave)
337                        ylabel = "1/sqrt(I)"
338                        break
339                endif
340                If (cmpstr("ln(Iq)",S_Value) == 0)
341                        SetScale d 0,0,"",yAxisWave
342                        yErrWave =ew/yAxisWave
343                        yWtWave = 1/yErrWave
344                        yAxisWave = ln(xw*yAxisWave)
345                        ylabel = "ln(q*I)"
346                        break
347                endif
348                If (cmpstr("ln(Iq^2)",S_Value) == 0)
349                        SetScale d 0,0,"",yAxisWave
350                        yErrWave = ew/yAxisWave
351                        yWtWave = 1/yErrWave
352                        yAxisWave = ln(xw*xw*yAxisWave)
353                        ylabel = "ln(I*q^2)"
354                        break
355                endif
356                //more ifs for each case
357               
358                // if selection not found, abort
359                DoAlert 0,"Y-axis scaling incorrect. Aborting"
360                Abort
361        while(0)        //end of "case" statement for y-axis scaling
362       
363       
364        //check for proper x-scaling selection
365        Variable low,high
366       
367        ControlInfo/W=A_FitPanel lolim
368        low = V_value
369        ControlInfo/W=A_FitPanel uplim
370        high = V_value
371        if ((high<low) || (high==low))
372                DoAlert 0,"Unphysical fitting limits - re-enter better values"
373                Abort
374        endif
375       
376        ControlInfo/W=A_FitPanel xModel
377        xstr = S_Value
378        do
379                // make the new yaxis wave
380                Duplicate/o xw xAxisWave
381                If (cmpstr("q",S_Value) == 0)   
382                        SetScale d 0,0,"A^-1",xAxisWave
383                        xAxisWave = xw
384                        xlabel = "q"
385                        xlow = low
386                        xhigh = high
387                        break   
388                endif
389                If (cmpstr("q^2",S_Value) == 0)
390                        SetScale d 0,0,"A^-2",xAxisWave
391                        xAxisWave = xw*xw
392                        xlabel = "q^2"
393                        xlow = low^2
394                        xhigh = high^2
395                        break   
396                endif
397                If (cmpstr("log(q)",S_Value) == 0)     
398                        SetScale d 0,0,"",xAxisWave
399                        xAxisWave = log(xw)
400                        xlabel = "log(q)"
401                        xlow = log(low)
402                        xhigh = log(high)
403                        break   
404                endif
405                If (cmpstr("q^c",S_Value) == 0)
406                        SetScale d 0,0,"",xAxisWave
407                        xAxisWave = xw^pow_c
408                        xlabel = "q^"+num2str(pow_c)
409                        xlow = low^pow_c
410                        xhigh = high^pow_c
411                        break
412                endif
413       
414                //more ifs for each case
415               
416                // if selection not found, abort
417                DoAlert 0,"X-axis scaling incorrect. Aborting"
418                Abort
419        while(0)        //end of "case" statement for x-axis scaling
420
421        //plot the data
422       
423//      String cleanLastFileName = "root:"+CleanupName(gLastFileName,0)
424        If(WinType("A_FitWindow") == 0)
425                Display /W=(5,42,480,400)/K=1 yAxisWave vs xAxisWave
426                ModifyGraph mode=3,standoff=0,marker=8,opaque=1
427                ErrorBars/T=0 yAxisWave Y,wave=(yErrWave,yErrWave)
428                DoWindow/C A_FitWindow
429        else
430                //window already exists, just bring to front for update
431                DoWindow/F A_FitWindow
432                // remove old text boxes
433                TextBox/K/N=text_1
434                TextBox/K/N=text_2
435                TextBox/K/N=text_3
436        endif
437        SetAxis/A
438        ModifyGraph tickUnit=1          //suppress tick units in labels
439        TextBox/C/N=textLabel/A=RB "File = "+baseStr
440        //clear the old fit from the window, if it exists
441        RemoveFromGraph/W=A_FitWindow/Z fit_yAxisWave
442       
443        // add the cursors if desired...       
444        //see if the user wants to use the data specified by the cursors - else use numerical values
445       
446        ControlInfo/W=A_FitPanel check0         //V_value = 1 if it is checked, meaning yes, use cursors
447        yes_cursors = V_value
448
449        DoWindow/F A_FitWindow
450        ShowInfo
451        if(yes_cursors)
452                xlow = xAxisWave[xcsr(A)]
453                xhigh = xAxisWave[xcsr(B)]
454                if(xlow > xhigh)
455                        xhigh = xlow
456                        xlow = xAxisWave[xcsr(B)]
457                endif
458//              Print xlow,xhigh
459        else
460                FindLevel/P/Q xAxisWave, xlow
461                if(V_flag == 1)                 //level NOT found
462                        DoAlert 0,"Lower q-limit not in experimental q-range. Re-enter a better value"
463                        //DoWindow/K A_FitWindow
464                        //Abort
465                endif
466                Cursor/P A, yAxisWave,trunc(V_LevelX)+1
467                ylow = V_LevelX
468                FindLevel/P/Q xAxisWave, xhigh
469                if(V_flag == 1)
470                        DoAlert 0,"Upper q-limit not in experimental q-range. Re-enter a better value"
471                        //DoWindow/K A_FitWindow
472                        //Abort
473                endif
474                Cursor/P B, yAxisWave,trunc(V_LevelX)
475                yhigh = V_LevelX
476        endif   //if(V_value)
477        //SetAxis bottom,xlow,xhigh
478        //SetAxis left,ylow,yhigh
479        Label left ylabel
480        Label bottom xlabel     //E denotes "scaling"  - may want to use "units" instead       
481
482End
483
484
485//button procedure that is activated to "DotheFit"
486//the panel is parsed for proper fitting limits
487// the appropriate linearization is formed (in the Rescale_Data() function)
488// and the fit is done,
489//and the results are plotted
490// function works in root level data folder (where the loaded 1-d data will be)
491Function A_DispatchModel(GoFit) : ButtonControl
492        String GoFit
493
494        //check for the FitWindow - to make sure that there is data to fit
495        If(WinType("A_FitWindow") == 0)         //if the window doesn't exist
496                Abort "You must Load and Plot a File before fitting the data"
497        endif
498       
499        // rescale the data, to make sure it's as selected on the panel
500        ControlInfo/W=A_FitPanel $"ywave"
501        String partialName = CleanupName(S_value,0)
502        A_Rescale_Data("root:"+partialName+":")
503       
504        // now go do the fit
505       
506// get the current low and high q values for fitting
507        Variable low,high
508       
509        ControlInfo/W=A_FitPanel lolim
510        low = V_value
511        ControlInfo/W=A_FitPanel uplim
512        high = V_value
513        if ((high<low) || (high==low))
514                DoAlert 0,"Unphysical fitting limits - re-enter better values"
515                Abort
516        endif
517
518        //try including residuals on the graph /R=residWave, explicitly place on new axis
519        //if only /R used, residuals are automatically placed on graph
520       
521        CurveFit line yAxisWave(xcsr(A),xcsr(B)) /X=xAxisWave /W=yWtWave /D 
522        //CurveFit line yAxisWave(xcsr(A),xcsr(B)) /X=xAxisWave /W=yWtWave  /R /D 
523        ModifyGraph rgb(fit_yAxisWave)=(0,0,0)
524// annotate graph, filtering out special cases of Guinier fits
525// Text Boxes must be used, since ControlBars on graphs DON'T print out
526       
527        // need access to Global wave, result of fit
528        //ystr and xstr are the axis strings - filter with a do-loop
529        String ystr="",xstr=""
530        //ControlInfo/W=A_FitPanel ywave
531        Wave xw = $("root:"+partialName+":"+partialName + "_q")
532        ControlInfo/W=A_FitPanel yModel
533        ystr = S_Value
534        ControlInfo/W=A_FitPanel xModel
535        xstr = S_Value
536       
537        WAVE W_coef=W_coef
538        WAVE W_sigma=W_sigma
539        String textstr_1,textstr_2,textstr_3 = ""
540        Variable rg,rgerr,minfit,maxfit,izerr
541       
542        textstr_1 = "Slope = " + num2str(W_coef[1]) + " ± " + num2str(W_sigma[1])
543        textstr_1 += "\rIntercept = " + num2str(W_coef[0]) + " ± " + num2str(W_sigma[0])
544        textstr_1 += "\rChi-Squared =  " + num2str(V_chisq/(V_npnts - 3))
545       
546        minfit = xw[xcsr(A)]
547        maxfit = xw[xcsr(B)]
548        textstr_2 = "Qmin =  " + num2str(minfit)
549        textstr_2 += "\rQmax =  " + num2str(maxfit)
550       
551        //model-specific calculations - I(0), Rg, etc.
552        //put these in textstr_3, at bottom
553        do
554                If (cmpstr("I",ystr) == 0)
555                        textstr_3 = "I(q=0) =  "  + num2str(W_coef[0])
556                        break   
557                endif
558                If (cmpstr("ln(I)",ystr) == 0)
559                        textstr_3 = "I(q=0) =  "  + num2str(exp(W_coef[0]))
560                        if(cmpstr("q^2",xstr) == 0)     //then a Guinier plot for a sphere (3-d)
561                                rg = sqrt(-3*W_coef[1])
562                                rgerr = 3*W_sigma[1]/(2*rg)
563                                textstr_3 += "\rRg (A) = " + num2str(rg) + " ± " + num2str(rgerr)
564                                textstr_3 += "\r" + num2str(rg*minfit) + " < Rg*q < " + num2str(rg*maxfit)
565                                break
566                        endif
567                        break   
568                endif
569                If (cmpstr("log(I)",ystr) == 0)
570                        if(cmpstr("log(q)",xstr) !=0 )  //extrapolation is nonsense
571                                textstr_3 = "I(q=0) =  "  + num2str(10^(W_coef[0]))
572                        endif
573                        break   
574                endif
575                If (cmpstr("1/I",ystr) == 0)
576                        izerr = abs(1/W_coef[0] - 1/(W_coef[0]+W_sigma[0]))
577                        textstr_3 = "I(q=0) =  "  + num2str(1/W_coef[0])+" ± " + num2str(izerr)
578                        break
579                endif
580                If (cmpstr("I^a",ystr) == 0)
581                        //nothing
582                        break
583                endif
584                If (cmpstr("Iq^a",ystr) == 0)
585                        //nothing
586                        break
587                endif
588                If (cmpstr("I^a q^b",ystr) == 0)
589                        //nothing
590                        break
591                endif
592                If (cmpstr("1/sqrt(I)",ystr) == 0)
593                        textstr_3 = "I(q=0) =  "  + num2str((W_coef[0])^2)
594                        break
595                endif
596                If (cmpstr("ln(Iq)",ystr) == 0)
597                        //nothing
598                        if(cmpstr("q^2",xstr) == 0)     //then a x-sect Guinier plot for a rod (2-d)
599                                // rg now is NOT the radius of gyration, but the x-sect DIAMETER
600                                rg = 4*sqrt(-W_coef[1])
601                                rgerr = 8*W_sigma[1]/rg
602                                textstr_3 = "Rod diameter (A) = " + num2str(rg) + " ± " + num2str(rgerr)
603                                textstr_3 += "\r" + num2str(rg*minfit) + " < Rg*q < " + num2str(rg*maxfit)
604                                break
605                        endif
606                        break
607                endif
608                If (cmpstr("ln(Iq^2)",ystr) == 0)
609                        //nothing
610                        if(cmpstr("q^2",xstr) == 0)     //then a 1-d Guinier plot for a sheet
611                                // rg now is NOT the radius of gyration, but the thickness
612                                rg = sqrt(-12*W_coef[1])
613                                rgerr = 6*W_sigma[1]/(2*rg)
614                                textstr_3 = "Platelet thickness (A) = " + num2str(rg) + " ± " + num2str(rgerr)
615                                textstr_3 += "\r" + num2str(rg*minfit) + " < Rg*q < " + num2str(rg*maxfit)
616                                break
617                        endif
618                        break
619                endif
620               
621        while(0)
622        //kill the old textboxes, if they exist
623        TextBox/W=A_FitWindow/K/N=text_1
624        TextBox/W=A_FitWindow/K/N=text_2
625        TextBox/W=A_FitWindow/K/N=text_3
626        // write the new text boxes
627        TextBox/W=A_FitWindow/N=text_1/A=LT textstr_1
628        TextBox/W=A_FitWindow/N=text_2/A=LC textstr_2
629        If (cmpstr("",textstr_3) != 0)          //only display textstr_3 if it isn't null
630                TextBox/W=A_FitWindow/N=text_3/A=LB textstr_3
631        endif
632       
633        //adjust the plot range to reflect the actual fitted range
634        //cursors are already on the graph, done by Rescale_Data()
635        A_AdjustAxisToCursors()
636       
637End
638
639// adjusts both the x-axis scaling  and y-axis scaling to the cursor range
640// **cursors are already on the graph, done by Rescale_Data()
641//
642// will expand the scale to show an extra 5 points in each direction (if available)
643Function A_AdjustAxisToCursors()
644
645        DoWindow/F A_FitWindow
646        WAVE xAxisWave = root:xAxisWave
647        WAVE yAxisWave = root:yAxisWave
648        Variable xlow,xhigh,ylow,yhigh,yptlow,ypthigh
649        Variable extraPts = 5, num=numpnts(xAxisWave)
650       
651        String csrA = CsrInfo(A ,"A_FitWindow")
652        String csrB = CsrInfo(B ,"A_FitWindow")
653       
654        //x-levels, these are monotonic
655        Variable ptLow,ptHigh,tmp
656        ptLow = NumberByKey("POINT", csrA ,":" ,";")
657        ptHigh = NumberByKey("POINT", csrB ,":" ,";")
658        if(ptLow > ptHigh)
659                tmp= ptLow
660                ptLow=ptHigh
661                ptHigh=tmp
662        endif
663
664        // keep extended point range in bounds
665        ptLow = (ptLow-extraPts) >= 0 ? ptLow-extraPts : 0
666        ptHigh = (ptHigh+extraPts) <= (num-1) ? ptHigh + extraPts : num-1
667       
668        xlow = xAxisWave[ptLow]
669        xhigh = xAxisWave[ptHigh]
670//old way
671//      xlow = xAxisWave[xcsr(A)]
672//      xhigh = xAxisWave[xcsr(B)]
673//      if(xlow > xhigh)
674//              xhigh = xlow
675//              xlow = xAxisWave[xcsr(B)]
676//      endif
677       
678        //y-levels (old way)
679//      FindLevel/P/Q xAxisWave, xlow
680//      if(V_flag == 1)                 //level NOT found
681//              DoAlert 0,"Lower q-limit not in experimental q-range. Re-enter a better value"
682//      endif
683//      yptlow = V_LevelX
684//      FindLevel/P/Q xAxisWave, xhigh
685//      if(V_flag == 1)
686//              DoAlert 0,"Upper q-limit not in experimental q-range. Re-enter a better value"
687//      endif
688//      ypthigh = V_LevelX
689
690//      Print xlow,xhigh,yptlow,ypthigh
691//      Print yAxisWave[yptlow],yAxisWave[ypthigh]
692       
693
694        // make sure ylow/high are in the correct order, since the slope could be + or -
695        yhigh = max(yAxisWave[ptlow],yAxisWave[pthigh])
696        ylow = min(yAxisWave[ptlow],yAxisWave[pthigh])
697       
698//      Print ptLow,ptHigh
699//      print xlow,xhigh
700//      print ylow,yhigh
701       
702        SetAxis bottom,xlow,xhigh
703        SetAxis left ylow,yhigh
704       
705End
706
707///// procedures added from other SANS Reduction files
708//
709//
710
711//function called by the popups to get a file list of data that can be sorted
712// this procedure simply removes the raw data files from the string - there
713//can be lots of other junk present, but this is very fast...
714//
715// could also use the alternate procedure of keeping only file with the proper extension
716//
717// another possibility is to get a listing of the text files, but is unreliable on
718// Windows, where the data file must be .txt (and possibly OSX)
719//
720Function/S A_filterButtonProc(ctrlName)
721        String ctrlName
722
723        String list="",newList="",item=""
724        Variable num,ii
725       
726        //check for the path
727        PathInfo catPathName
728        if(V_Flag==0)
729                DoAlert 0, "Data path does not exist - pick the data path from the button on the FIT panel"
730                Return("")
731        Endif
732       
733        list = IndexedFile(catpathName,-1,"????")
734        num=ItemsInList(list,";")
735        //print "num = ",num
736        for(ii=(num-1);ii>=0;ii-=1)
737                item = StringFromList(ii, list  ,";")
738                //simply remove all that are not raw data files (SA1 SA2 SA3)
739                if( !stringmatch(item,"*.SA1*") && !stringmatch(item,"*.SA2*") && !stringmatch(item,"*.SA3*") )
740                        if( !stringmatch(item,".*") && !stringmatch(item,"*.pxp") && !stringmatch(item,"*.DIV"))                //eliminate mac "hidden" files, pxp, and div files
741                                newlist += item + ";"
742                        endif
743                endif
744        endfor
745        //remove VAX version numbers
746        newList = A_RemoveVersNumsFromList(newList)
747        //sort
748        newList = SortList(newList,";",0)
749
750        return newlist
751End
752
753
754
755
756
757
758//procedures to clean up after itself
759Function UnloadLinFit()
760
761        if (WinType("A_FitPanel") == 7)
762                DoWindow/K A_FitPanel
763        endif
764        if (WinType("A_FitWindow") != 0)
765                DoWindow/K $"A_FitWindow"
766        endif
767        SetDataFolder root:
768        Killwaves/Z xAxisWave,yAxisWave,yErrWave,residWave,yWtWave,fit_yAxisWave
769       
770        SVAR fileVerExt=root:Packages:NIST:SANS_ANA_EXTENSION
771        String fname="LinearizedFits"
772        Execute/P "DELETEINCLUDE \""+fname+fileVerExt+"\""
773        Execute/P "COMPILEPROCEDURES "
774end
775
776Menu "SANS Models"
777        Submenu "Packages"
778                "Unload Linear Fitting", UnloadLinFit()
779        End
780end
781
782Function A_FIT_PickPathButtonProc(ctrlName) : ButtonControl
783        String ctrlName
784
785        A_PickPath()
786        //pop the file menu
787        A_FIT_FilePopMenuProc("",1,"")
788End
Note: See TracBrowser for help on using the repository browser.