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

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

changed the number of significant digits visible in the Catalog table, so that the wavelength, SDD, and sample position don't show up as odd floating point values, when they're only off by a smidgen. If they are significantly off, the real value will be seen.

Modified the file loader for Linearized fits to correctly handle files that are loaded with file names that are too long. Now they are loaded and plotted correctly, as the plot manager does. Now, when fitting, if the file name is too long (from the popup) then the user is prompted to pick the data set, since I don't know which one it is anymore, since the name was changed. Not too big of an issue. Most (All, I hope) of the file writing routines now enforce short, compliant names. this is ticket #363

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