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

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

Several changes:
1) added /I=1 flag in several places (mostly the invariant) so that the error wave would be interpreted as the standard deviation, not 1/s (Jae_Hie pointed this out)
2) put error checking in ProDiv? to warn if the pixel centers are more than 5 pixels from the expected 65,65 for on-center or 105,65 for the offset (usually run at 20 cm offset)
3) commented out the line in WriteQIS that outputs 2D resolution information to QxQy? data. I just don't think it's correct yet, and the 2D resolution smearing is not ready either.

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)) /I=1 /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.