source: sans/Dev/trunk/NCNR_User_Procedures/Analysis/Packages/Wrapper_v40.ipf @ 911

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

Updated the NGB attenuator tables with Katie's new measurements from May 2013.

Made some changes to Auto-Fit to make it more useable. Will turn it "on" when documentation is finished.

Changed how the random deviate function is calculated to improve the estimates of multiple scattering. Now the q-range of integration is shifted to lower q for the USANS calculation (using very large objects). Also, the number of points used in the integration is chosen adaptively until a constant value of scattering cross section is obtained. There are still some functions where the integration fails (power laws). These will always fail. My best solution currently is to flag the times when the XS>100. Then the estimates are invalid. The 1D simulation is fine, the 2D is reasonably fine, but anything to do with multile scattering is incorrect.

File size: 72.7 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=4.10
3#pragma IgorVersion=6.1
4
5
6// this is the flag for the relative error = W_sigma/coef that will
7// trip the bold/red color of W_sigma in the table.
8//
9Constant kRelErrorTolerance=0.5
10
11//Macro OpenWrapperPanel()
12//      Init_WrapperPanel()
13//End
14
15Function Init_WrapperPanel()
16
17        if(itemsinlist(WinList("SA_includes_v400.ipf", ";","INCLUDE:6"),";") != 0)
18                //must be opening a v4.00 or earlier template
19                DoAlert 0,"This experiment was created with an old version (v4.0) of the macros. I'll try to make this work, but please start new work with a current version"
20        endif
21       
22        //make sure that folders exist - this is the first initialization to be called
23        NewDataFolder/O root:Packages
24        NewDataFolder/O root:Packages:NIST
25
26        //Create useful globals
27        Variable/G root:Packages:NIST:SANS_ANA_VERSION=4.10
28        String/G root:Packages:NIST:SANS_ANA_EXTENSION="_v40"
29        //Set this variable to 1 to force use of trapezoidal integration routine for USANS smearing
30        Variable/G root:Packages:NIST:USANSUseTrap = 0
31        Variable/G root:Packages:NIST:USANS_dQv = 0.117
32        Variable/G root:Packages:NIST:gUseGenCurveFit = 0                       //set to 1 to use genetic optimization
33                       
34        //Ugly. Put this here to make sure things don't break
35        String/G root:Packages:NIST:gXMLLoader_Title
36       
37       
38        //initializes preferences. this includes XML y/n, and SANS Reduction items.
39        // if they already exist, they won't be overwritten
40        Execute "Initialize_Preferences()"             
41       
42        DoWindow/F WrapperPanel
43        if(V_flag==0)
44                if(exists("root:Packages:NIST:coefKWStr")==0)
45                        String/G root:Packages:NIST:coefKWStr=""
46                endif
47                if(exists("root:Packages:NIST:suffixKWStr")==0)
48                        String/G root:Packages:NIST:suffixKWStr=""
49                endif
50                if(exists("root:Packages:NIST:paramKWStr")==0)
51                        String/G root:Packages:NIST:paramKWStr=""
52                endif
53                Execute "WrapperPanel()"
54        endif
55End
56
57////////
58//
59// if model is Smeared, search the DF for coefficients
60// if new DF chosen, need to reset
61// if new model function, need to reset table
62//
63// create hold_mod (0/1), constr_low_mod, constr_hi_mod
64// in either DF (smeared) or in root: (normal)
65// and put these in the table as needed
66//
67Window WrapperPanel()
68        PauseUpdate; Silent 1           // building window...
69        NewPanel /W=(459,44,1113,499)/N=wrapperPanel/K=1 as "Curve Fit Setup"
70        ModifyPanel fixedSize=1
71       
72        GroupBox grpBox_0,pos={18,11},size={390,113}
73        GroupBox grpBox_1,pos={426,10},size={207,113}
74        GroupBox grpBox_2 title="No Fit",pos={10,130},size={0,0},frame=1,fSize=10,fstyle=1,fColor=(39321,1,1)
75        GroupBox grpBox_3 title="",pos={10,150},size={0,0},frame=1,fSize=10,fstyle=1,fColor=(39321,1,1)
76
77        Button button_1,pos={280,57},size={120,20},proc=PlotModelFunction,title="Plot 1D Function"
78        Button button_2,pos={300,93},size={100,20},proc=AppendModelToTarget,title="Append 1D"
79        Button button_3,pos={300,20},size={100,20},proc=W_LoadDataButtonProc,title="Load 1D Data"
80        PopupMenu popup_0,pos={30,21},size={218,20},title="Data Set",proc=DataSet_PopMenuProc
81        PopupMenu popup_0,mode=1,value= #"W_DataSetPopupList()"
82        PopupMenu popup_1,pos={30,57},size={136,20},title="Function"
83        PopupMenu popup_1,mode=1,value= #"W_FunctionPopupList()",proc=Function_PopMenuProc
84        PopupMenu popup_2,pos={30,93},size={123,20},title="Coefficients"
85        PopupMenu popup_2,mode=1,value= #"W_CoefPopupList()",proc=Coef_PopMenuProc
86        CheckBox check_0,pos={430,19},size={79,14},title="Use Cursors?",value= 0
87        CheckBox check_0,proc=UseCursorsWrapperProc
88        CheckBox check_1,pos={430,42},size={74,14},title="Use Epsilon?",value= 0
89        CheckBox check_2,pos={430,65},size={95,14},title="Use Constraints?",value= 0
90        CheckBox check_3,pos={530,18},size={72,14},title="2D Functions?",value= 0
91        CheckBox check_3 proc=Toggle2DControlsCheckProc
92        CheckBox check_4,pos={430,85},size={72,14},title="Report?",value= 0
93        CheckBox check_5,pos={444,103},size={72,14},title="Save it?",value= 0
94        CheckBox check_6,pos={530,38},size={72,14},title="Use Residuals?",value= 0
95        CheckBox check_6,proc=UseResidualsCheckProc
96        CheckBox check_7,pos={530,57},size={72,14},title="Info Box?",value= 0
97        CheckBox check_7,proc=UseInfoTextBoxCheckProc
98        CheckBox check_8, pos={530,75}, size={72,14}, title="Rescale Axis?", value=0
99        CheckBox check_8,proc=UseRescaleAxisCheckProc
100        //change draw order to put button over text of checkbox
101        Button button_0,pos={520,93},size={100,20},proc=DoTheFitButton,title="Do 1D Fit"
102        Button button_4,pos={520,126},size={100,20},proc=FeedbackButtonProc,title="Feedback"
103        Button button_5,pos={520,150},size={100,20},proc=FitHelpButtonProc,title="Help"
104
105        Edit/W=(20,174,634,435)/HOST=# 
106        ModifyTable width(Point)=0
107        RenameWindow #,T0
108        SetActiveSubwindow ##
109EndMacro
110
111//open the Help file for the Fit Manager
112Function FitHelpButtonProc(ba) : ButtonControl
113        STRUCT WMButtonAction &ba
114
115        switch( ba.eventCode )
116                case 2: // mouse up
117                        // click code here
118                        DisplayHelpTopic/Z/K=1 "Fit Manager"
119                        if(V_flag !=0)
120                                DoAlert 0,"The Fit Manager Help file could not be found"
121                        endif
122                        break
123        endswitch
124
125        return 0
126End
127
128
129//open the trac page for feedback
130Function FeedbackButtonProc(ba) : ButtonControl
131        STRUCT WMButtonAction &ba
132
133        switch( ba.eventCode )
134                case 2: // mouse up
135                        // click code here
136                        OpenTracTicketPage()
137                        break
138        endswitch
139
140        return 0
141End
142
143
144//obvious use, now finds the most recent data loaded, finds the folder, and pops the menu with that selection...
145//
146Function W_LoadDataButtonProc(ba) : ButtonControl
147        STRUCT WMButtonAction &ba
148
149        switch( ba.eventCode )
150                case 2: // mouse up
151                        // click code here
152                        String  topGraph= WinName(0,1)
153                        if(strlen(topGraph) != 0)
154                                DoWindow/F $topGraph                    //so that the panel is not on top
155                        endif
156                        Execute "A_LoadOneDData()"
157                       
158                        ControlUpdate/W=WrapperPanel popup_0
159                        //instead of a simple controlUpdate, better to pop the menu to make sure that the other menus follow
160                        // convoluted method to find the right item and pop the menu.
161
162                        // data is plotted, so get the "new" top graph
163                        topGraph= WinName(0,1)  //this is the topmost graph, and should exist, but...
164                        if(cmpstr(topGraph,"")==0)
165                                return(0)
166                        endif
167                        String list,folderStr
168                        Variable num
169                        list = TraceNameList(topGraph,";",1)            //want the last item in the list
170                        num= ItemsInList(list)
171                        FolderStr = StringFromList(num-1,list,";")
172                        folderStr = folderStr[0,strlen(folderStr)-3]            //remove the "_i" that the loader enforced
173                        list = W_DataSetPopupList()
174                        num=WhichListItem(folderStr,list,";",0,0)
175                        if(num != -1)
176                                PopupMenu popup_0,mode=num+1,win=WrapperPanel
177                                ControlUpdate/W=WrapperPanel popup_0
178                               
179                                // fake mouse up to pop the menu
180                                Struct WMPopupAction ps
181                                ps.eventCode = 2                //fake mouse up
182                                DataSet_PopMenuProc(ps)
183                        endif
184                        break
185        endswitch
186       
187        return 0
188End
189
190
191// is there a simpler way to do this? I don't think so.
192Function/S W_DataSetPopupList()
193
194        String str=GetAList(4)
195
196        if(strlen(str)==0)
197                str = "No data loaded"
198        endif
199        str = SortList(str)
200       
201        return(str)
202End
203
204
205// show the available models
206// not the f*(cw,xw) point calculations
207// not the *X(cw,xw) XOPS
208//
209// KIND:10 should show only user-defined curve fitting functions
210// - not XOPs
211// - not other user-defined functions
212Function/S W_FunctionPopupList()
213        String list,tmp
214        //get every user defined curve fit function, remove everything the user doesn't need to see...
215        list = User_FunctionPopupList()         
216
217        if(strlen(list)==0)
218                list = "No functions plotted"
219        endif
220       
221        list = SortList(list)
222        return(list)
223End
224
225
226// show all the appropriate coefficient waves
227//
228// also need to search the folder listed in "data set" popup
229// for smeared coefs
230//
231// - or - restrict the coefficient list based on the model function
232// - new way, filter the possible values based on the data folder and function
233Function/S W_CoefPopupList()
234
235        String notPlotted="Please plot the function"
236        ControlInfo/W=wrapperpanel popup_1
237        String funcStr=S_Value
238        String coefStr=getFunctionCoef(funcStr)
239       
240        if(cmpstr(coefStr,"")==0)               //no correspondence in the KW string
241                return(notPlotted)
242        endif
243       
244       
245        //found a coefficient wave - only two places to look
246        // is it in the root folder?
247        if(exists("root:"+coefStr) != 0)
248                return(coefStr)
249        endif
250       
251        // is it in the data folder?
252        ControlInfo/W=wrapperpanel popup_0
253        String folderStr=S_Value
254        if(exists("root:"+folderStr+":"+coefStr) != 0)
255                return(coefStr)
256        endif
257
258        return(notPlotted)
259End
260
261// show all the appropriate coefficient waves
262//
263// also need to search the folder listed in "data set" popup
264// for smeared coefs
265//
266// - or - restrict the coefficient list based on the model function
267//
268// --old way
269//Function/S W_CoefPopupList()
270//      String list
271//      setDataFolder root:
272//      list = WaveList("coef*",";","")
273//     
274//      ControlInfo/W=wrapperpanel popup_0
275//      if(V_Value != 0)                //0== no items in menu
276//              if(DataFolderExists("root:"+S_Value))
277//                      SetDataFolder $("root:"+S_Value)
278//                      list += WaveList("*coef*",";","")
279//              endif
280//      endif
281//     
282//      // tmp coefficients that aren't being cleaned up from somewhere...
283//      list = RemoveFromList("temp_coef_1;temp_coef_2;", list  ,";")
284//
285//      if(strlen(list)==0)
286//              list = "No functions plotted"
287//      endif
288//      list = SortList(list)
289//     
290////    Print itemsinlist(list,";")
291//     
292//      setDataFolder root:
293//      return(list)
294//End
295
296// if the coefficients are changed, then update the table
297//
298//update the table
299// may be easier to just kill the subwindow (table) and create a new one
300// need to set/reset all of the waves in the table
301//
302// !! only respond to mouse up
303//
304Function Coef_PopMenuProc(pa) : PopupMenuControl
305        STRUCT WMPopupAction &pa
306
307        switch( pa.eventCode )
308                case 2: // mouse up
309                        Variable popNum = pa.popNum
310                        String popStr = pa.popStr
311                        ControlInfo/W=WrapperPanel popup_1
312                        String funcStr=S_Value
313                        String suffix = getModelSuffix(funcStr)
314                        ControlInfo/W=WrapperPanel popup_0
315                        String folderStr=S_Value
316                       
317                        if(cmpstr(popStr,"Please plot the function")==0)
318//                              Print "function not plotted"
319                                return(0)
320                        endif
321
322// this if/else/endif should not ever return an error alert     
323// it should simply set the data folder properly       
324                        if(DataFolderExists("root:"+folderStr))
325                                SetDataFolder $("root:"+folderStr)
326                                if(!exists(popStr))
327                                        // must be unsmeared model, work in the root folder
328                                        SetDataFolder root:                             
329                                        if(!exists(popStr))             //this should be fine if the coef filter is working, but check anyhow
330                                                DoAlert 0,"the coefficient and data sets do not match (1)"
331                                                return 0
332                                        endif
333                                endif
334                        else
335                                // must be unsmeared model, work in the root folder
336                                SetDataFolder root:     
337                                if(!exists(popStr))             //this should be fine if the coef filter is working, but check anyhow
338                                        DoAlert 0,"the coefficient and data sets do not match (2)"
339                                        return 0
340                                endif
341                        endif
342                       
343                        // farm the work out to another function?
344                        Variable num=numpnts($popStr)
345                        // make the necessary waves if they don't exist already
346                        if(exists("Hold_"+suffix) == 0)
347                                Make/O/D/N=(num) $("epsilon_"+suffix),$("Hold_"+suffix)
348                                Make/O/T/N=(num) $("LoLim_"+suffix),$("HiLim_"+suffix)
349                                Wave eps = $("epsilon_"+suffix)
350                                Wave coef=$popStr
351                                if(eps[0] == 0)         //if eps already if filled, don't change it
352                                        eps = abs(coef*1e-4) + 1e-10                    //default eps is proportional to the coefficients
353                                endif
354                        endif
355                        // default epsilon values, sometimes needed for the fit
356                       
357                        WAVE/T LoLim = $("LoLim_"+suffix)
358                        WAVE/T HiLim = $("HiLim_"+suffix)
359                       
360                        // clear the table (a subwindow)
361                        DoWindow/F WrapperPanel                         // ?? had to add this in during all of the cursor meddling...
362                        KillWindow wrapperPanel#T0
363                        Edit/W=(20,174,634,435)/HOST=wrapperPanel
364                        RenameWindow #,T0
365                        // get them onto the table
366                        // how do I get the parameter name?
367                        String param = getFunctionParams(funcStr)
368                        AppendtoTable/W=wrapperPanel#T0 $param,$(popStr)
369                        AppendToTable/W=wrapperPanel#T0 $("Hold_"+suffix),$("LoLim_"+suffix),$("HiLim_"+suffix),$("epsilon_"+suffix)
370                        ModifyTable/W=wrapperPanel#T0 width(Point)=0
371                       
372                        SetDataFolder root:
373                        break
374        endswitch
375
376        return 0
377End
378
379// if the Function is changed, then update the coef popup (if possible) and then the table (if possible)
380//
381// !! only respond to mouse up
382//
383Function Function_PopMenuProc(pa) : PopupMenuControl
384        STRUCT WMPopupAction &pa
385
386        switch( pa.eventCode )
387                case 2: // mouse up
388                        Variable popNum = pa.popNum
389                        String funcStr = pa.popStr
390                        String coefStr = W_CoefPopupList()
391                       
392//                      Print "coefStr = ",coefStr
393                       
394                        ControlInfo/W=WrapperPanel popup_0
395                        String folderStr=S_Value
396                       
397                        String listStr = W_CoefPopupList()
398                        Variable num=WhichListItem(coefStr, listStr, ";")
399                        String str=StringFromList(num, listStr  ,";")
400//                      print "str = ",str
401                        //set the item in the coef popup, and pop it
402                        PopupMenu popup_2 win=WrapperPanel,mode=(num+1)
403                       
404                        Struct WMPopupAction ps
405                        ps.eventCode = 2                //fake mouse up
406                        ps.popStr = str
407                        Coef_PopMenuProc(ps)
408                       
409                        SetDataFolder root:
410                        break
411        endswitch
412
413        return 0
414End
415
416// if the Data Set is changed, then update the function (if possible)
417// and the coef popup (if possible) and then the table (if possible)
418//
419// !! only respond to mouse up here, and simply send a fake mouse up
420// to the function pop, which will do what it can do
421//
422Function DataSet_PopMenuProc(pa) : PopupMenuControl
423        STRUCT WMPopupAction &pa
424       
425        switch( pa.eventCode )
426                case 2: // mouse up
427                        // make sure that the cursors are on/off appropriately
428                        // let the cursors checkbox decide what to do, sending the current state
429                        ControlInfo/W=WrapperPanel check_0
430                        STRUCT WMCheckboxAction cba
431                        cba.eventCode = 2
432                        cba.checked = V_Value
433                        UseCursorsWrapperProc(cba)
434                                       
435                        // then cascade the function/coefficient popups
436                        Struct WMPopupAction ps
437                        ps.eventCode = 2                //fake mouse up
438                        Function_PopMenuProc(ps)
439                       
440                        SetDataFolder root:
441                        break
442        endswitch
443
444        return 0
445End
446
447
448// - this is based on stringent "PlotNNN" naming requirements
449//
450//  ???
451// - how to kill the generated table and graph, that are not needed now
452//
453Function PlotModelFunction(ba) : ButtonControl
454        STRUCT WMButtonAction &ba
455
456        String folderStr,funcStr,coefStr,cmdStr=""
457        Variable useCursors,useEps,useConstr
458       
459        Variable killWhat=0             //kill nothing as default
460       
461        switch( ba.eventCode )
462                case 2: // mouse up
463                        ControlInfo/W=WrapperPanel popup_0
464                        folderStr=S_Value
465                       
466                        ControlInfo/W=WrapperPanel popup_1
467                        funcStr=S_Value
468                       
469                        // maybe nothing has been loaded yet...
470                        if(cmpstr(funcStr,"No functions plotted") == 0)
471                                break
472                        endif
473                       
474                        // check for smeared or smeared function
475                        if(stringmatch(funcStr, "Smear*" )==1)
476                                //it's a smeared model
477                                // check for the special case of RPA that has an extra parameter
478                                if(strsearch(funcStr, "RPAForm", 0 ,0) == -1)
479                                        sprintf cmdStr, "Plot%s(\"%s\")",funcStr,folderStr              //not RPA
480                                else
481                                        sprintf cmdStr, "Plot%s(\"%s\",)",funcStr,folderStr             //yes RPA, leave a comma for input
482                                endif
483                                killWhat = 1
484                        else
485                                // it's not,    don't kill the graph, just the table           
486                                sprintf cmdStr, "Plot%s()",funcStr
487                                killWhat = 2
488                        endif
489                       
490                        //Print cmdStr
491                        Execute cmdStr
492                       
493                        //pop the function menu to set the proper coefficients
494                        DoWindow/F WrapperPanel
495                        STRUCT WMPopupAction pa
496                        pa.popStr = funcStr
497                        pa.eventcode = 2
498                        Function_PopMenuProc(pa)
499       
500                        KillTopGraphAndTable(killWhat)          // crude
501       
502                        break
503        endswitch
504       
505        return 0
506End
507
508// passing 0 kills nothing
509// passing 1 kills the top graph and table
510// passing 2 kills the top table only
511//
512Function KillTopGraphAndTable(killwhat)
513        Variable killWhat
514       
515        String topGraph= WinName(0,1)   //this is the topmost graph     
516        String topTable= WinName(0,2)   //this is the topmost table
517
518        if(killWhat == 0)
519                return(0)
520        endif
521       
522        if(killWhat == 1)
523                KillWindow $topGraph
524                KillWindow $topTable
525        endif
526       
527        if(killWhat == 2)
528                KillWindow $topTable
529        endif
530       
531        return(0)
532End
533
534// How to bypass the step of plot and append?
535//
536// do it in two separate events
537//
538Function AppendModelToTarget(ba) : ButtonControl
539        STRUCT WMButtonAction &ba
540
541        String coefStr,suffix,yWStr,xWStr,folderStr,funcStr
542       
543        switch( ba.eventCode )
544                case 2: // mouse up                     
545                        ControlInfo/W=WrapperPanel popup_2
546                        coefStr=S_Value
547                       
548                        ControlInfo/W=WrapperPanel popup_1
549                        funcStr=S_Value
550                        suffix = getModelSuffix(funcStr)
551                       
552                        // check for smeared or smeared function
553                        if(stringmatch(coefStr, "smear*" )==1)
554                                //it's a smeared model
555                                ControlInfo/W=WrapperPanel popup_0
556                                folderStr=S_Value
557                                xWStr = "root:"+folderStr+":smeared_qvals"
558                                ywStr = "root:"+folderStr+":smeared_"+suffix
559                        else
560                                // it's not, so it's in the root folder
561                                xWStr = "xwave_"+suffix
562                                yWStr = "ywave_"+suffix
563                        endif
564                       
565                        Wave/Z yw = $yWStr
566                        Wave/Z xw = $xWStr
567                        if(WaveExists(yw) && WaveExists(xw))
568                                AppendtoGraph yw vs xw
569                        else
570                                DoAlert 0,"The selected model has not been plotted for the selected data set."
571                        endif
572                        break
573        endswitch
574       
575        return 0
576End
577
578
579// this should parse the panel and call the FitWrapper() function
580Function DoTheFitButton(ba) : ButtonControl
581        STRUCT WMButtonAction &ba
582
583        String folderStr,funcStr,coefStr
584        Variable useCursors,useEps,useConstr,useResiduals,useTextBox, useRescaleAxis
585       
586        switch( ba.eventCode )
587                case 2: // mouse up
588                        ControlInfo/W=WrapperPanel popup_0
589                        folderStr=S_Value
590                       
591                        ControlInfo/W=WrapperPanel popup_1
592                        funcStr=S_Value
593                       
594                        ControlInfo/W=WrapperPanel popup_2
595                        coefStr=S_Value
596                       
597                        ControlInfo/W=WrapperPanel check_0
598                        useCursors=V_Value
599                        ControlInfo/W=WrapperPanel check_1
600                        useEps=V_Value
601                        ControlInfo/W=WrapperPanel check_2
602                        useConstr=V_Value
603                       
604                        ControlInfo/W=WrapperPanel check_6
605                        useResiduals=V_Value
606                       
607                        ControlInfo/W=WrapperPanel check_7
608                        useTextBox = V_Value
609                       
610                        ControlInfo/W=WrapperPanel check_8
611                        useRescaleAxis = V_Value
612                       
613                        if(!CheckFunctionAndCoef(funcStr,coefStr))
614                                DoAlert 0,"The coefficients and function type do not match. Please correct the selections in the popup menus."
615                                break
616                        endif
617                       
618                        FitWrapper(folderStr,funcStr,coefStr,useCursors,useEps,useConstr,useResiduals,useTextBox,useRescaleAxis)
619                       
620                        //      DoUpdate (does not work!)
621                        //?? why do I need to force an update ??
622                        if(!exists("root:"+folderStr+":"+coefStr))
623                                Wave w=$coefStr
624                        else
625                                Wave w=$("root:"+folderStr+":"+coefStr) //smeared coefs in data folder
626                        endif
627                        w[0] += 1e-6
628                        w[0] -= 1e-6
629       
630                        break
631        endswitch
632       
633        return 0
634End
635
636Function CheckFunctionAndCoef(funcStr,coefStr)
637        String funcStr,coefStr
638       
639        SVAR listStr=root:Packages:NIST:coefKWStr
640        String properCoefStr = StringByKey(funcStr, listStr  ,"=",";",0)
641        if(cmpstr("",properCoefStr)==0)
642                return(0)               //false, no match found, so properCoefStr is returned null
643        endif
644        if(cmpstr(coefStr,properCoefStr)==0)
645                return(1)               //true, the coef is the correct match
646        endif
647        return(0)                       //false, wrong coef
648End
649
650/////////////////////////////////
651
652// wrapper to do the desired fit
653//
654// folderStr is the data folder for the desired data set
655//
656//
657Function FitWrapper(folderStr,funcStr,coefStr,useCursors,useEps,useConstr,useResiduals,useTextBox,useRescaleAxis)
658        String folderStr,funcStr,coefStr
659        Variable useCursors,useEps,useConstr,useResiduals,useTextBox,useRescaleAxis
660
661        String suffix=getModelSuffix(funcStr)
662       
663        SetDataFolder $("root:"+folderStr)
664        if(!exists(coefStr))
665                // must be unsmeared model, work in the root folder
666                SetDataFolder root:                             
667                if(!exists(coefStr))            //this should be fine if the coef filter is working, but check anyhow
668                        DoAlert 0,"the coefficient and data sets do not match"
669                        return 0
670                endif
671        endif
672               
673        WAVE cw=$(coefStr)     
674        Wave hold=$("Hold_"+suffix)
675        Wave/T lolim=$("LoLim_"+suffix)
676        Wave/T hilim=$("HiLim_"+suffix)
677       
678        if(useEps)
679                Wave eps=$("epsilon_"+suffix)
680        endif
681// fill a struct instance whether I need one or not
682        String DF="root:"+folderStr+":"
683       
684        Struct ResSmearAAOStruct fs
685        WAVE/Z resW = $(DF+folderStr+"_res")                    //these may not exist, if 3-column data is used
686        WAVE/Z fs.resW =  resW
687        WAVE yw=$(DF+folderStr+"_i")
688        WAVE xw=$(DF+folderStr+"_q")
689        WAVE sw=$(DF+folderStr+"_s")
690        Wave fs.coefW = cw
691        Wave fs.yW = yw
692        Wave fs.xW = xw
693       
694        Duplicate/O yw $(DF+"FitYw")
695        WAVE fitYw = $(DF+"FitYw")
696        fitYw = NaN
697       
698        Variable useResol=0,isUSANS=0,val
699        if(stringmatch(funcStr, "Smear*"))              // if it's a smeared function, need a struct
700                useResol=1
701        endif
702        if(dimsize(resW,1) > 4)
703                isUSANS=1
704        endif
705       
706        // do not construct constraints for any of the coefficients that are being held
707        // -- this will generate an "unknown error" from the curve fitting
708        // -- if constraints are not used, the constr wave is killed. This apparently
709        // confuses the /NWOK flag, since there is not even a null reference present. So generate one.
710        if(useConstr)
711                Make/O/T/N=0 constr
712                String constraintExpression
713                Variable i, nPnts=DimSize(lolim, 0),nextRow=0
714                for (i=0; i < nPnts; i += 1)
715                        if (strlen(lolim[i]) > 0 && hold[i] == 0)
716                                InsertPoints nextRow, 1, constr
717                                sprintf constraintExpression, "K%d > %s", i, lolim[i]
718                                constr[nextRow] = constraintExpression
719                                nextRow += 1
720                        endif
721                        if (strlen(hilim[i]) > 0 && hold[i] == 0)
722                                InsertPoints nextRow, 1, constr
723                                sprintf constraintExpression, "K%d < %s", i, hilim[i]
724                                constr[nextRow] = constraintExpression
725                                nextRow += 1
726                        endif
727                endfor
728        else
729                Wave/T/Z constr = constr
730                KillWaves/Z constr
731                Wave/T/Z constr = constr                //this is intentionally a null reference
732        endif
733
734        // 20JUN if useCursors is true, and there are no cursors on the specified data set, uncheck and set to false
735        // this is a last line of defense, and should never actually do anything...
736        if(useCursors)
737                useCursors = AreCursorsCorrect(folderStr)
738        endif
739        //if useCursors, and the data is USANS, need to recalculate the matrix if the range is new
740        Variable pt1,pt2,newN,mPt1,mPt2
741        String noteStr
742        if(useCursors && isUSANS )
743                //where are the cursors, and what is the status of the current matrix?
744                if(pcsr(A) > pcsr(B))
745                        pt1 = pcsr(B)
746                        pt2 = pcsr(A)
747                else
748                        pt1 = pcsr(A)
749                        pt2 = pcsr(B)
750                endif
751               
752                noteStr = note(resW)
753                mPt1 = NumberByKey("P1",noteStr,"=",";")
754                mPt2 = NumberByKey("P2",noteStr,"=",";")
755                if((mPt1 != pt1) || (mPt2 != pt2) )
756                        // need to recalculate
757                        USANS_RE_CalcWeights(folderStr,pt1,pt2)
758                        Print "Done recalculating the matrix"
759                endif
760               
761                Wave trimResW=$(DF+folderStr+"_res"+"t")        //put the trimmed resW in the struct for the fit!
762                Wave fs.resW=trimResW
763        endif
764        if(useCursors)
765                //find the points so that genetic optimization can use them
766                if(pcsr(A) > pcsr(B))
767                        pt1 = pcsr(B)
768                        pt2 = pcsr(A)
769                else
770                        pt1 = pcsr(A)
771                        pt2 = pcsr(B)
772                endif
773        else
774                //if cursors are not being used, find the first and last points of the data set, and pass them
775                pt1 = 0
776                pt2 = numpnts(yw)-1
777        endif
778               
779// create these variables so that FuncFit will set them on exit
780        Variable/G V_FitError=0                         //0=no err, 1=error,(2^1+2^0)=3=singular matrix
781        Variable/G V_FitQuitReason=0            //0=ok,1=maxiter,2=user stop,3=no chisq decrease
782
783        NVAR useGenCurveFit = root:Packages:NIST:gUseGenCurveFit
784// don't use the auto-destination with no flag, it doesn't appear to work correctly
785// dispatch the fit
786
787// currently, none of the fit functions are defined as threadsafe, so I don't think that the /NTHR flag really
788// does anything. The functions themselves can be threaded since they are AAO, and that is probably enough,
789// since it doesn't make much sense to thread threads. In addition, there is a little-publicized warning
790// in the WM help file that /C=texWave cannot be used to specify constraints for threadsafe functions!
791// The textwave would have to be parsed into a constraint matrix first, then passed as /C={cMat,cVec}.
792// -- just something to watch out for.
793
794// now two more flags... ,useResiduals,useTextBox
795        Variable tb = 1+2+4+8+16+256+512                //See CurveFit docs for bit settings for /TBOX flag
796
797        do
798                Variable t0 = stopMStimer(-2)           // corresponding print is at the end of the do-while loop (outside)
799
800
801                if(useGenCurveFit)
802               
803#if !(exists("GenCurveFit"))
804                        // XOP not available
805                        useGenCurveFit = 0
806                        Abort "Genetic Optimiztion XOP not available. Reverting to normal optimization."       
807#endif
808                        //send everything to a function, to reduce the clutter
809                        // useEps and useConstr are not needed
810                        // pass the structure to get the current waves, including the trimmed USANS matrix
811                        //
812                        // I don't know that GetCurveFit can do residuals, so I'm not passing that flag, or the text box flag
813                        //
814                        Variable chi,pt
815
816                        chi = DoGenCurveFit(useResol,useCursors,sw,fitYw,fs,funcStr,getHStr(hold),val,lolim,hilim,pt1,pt2)
817                        pt = val
818
819                        break
820                       
821                endif
822               
823                // now useCursors, useEps, and useConstr are all handled w/ /NWOK
824                // so there are only three conditions to test == 1 + 3 + 3 + 1 = 8 conditions
825               
826                if(useResol && useResiduals && useTextBox)              //do it all
827                        FuncFit/H=getHStr(hold) /M=2 /NTHR=0 /TBOX=(tb) $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /STRC=fs /R /NWOK
828                        break
829                endif
830               
831                if(useResol && useResiduals)            //res + resid
832                        FuncFit/H=getHStr(hold) /M=2 /NTHR=0 $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /STRC=fs /R /NWOK
833                        break
834                endif
835
836               
837                if(useResol && useTextBox)              //res + text
838                        FuncFit/H=getHStr(hold) /M=2 /NTHR=0 /TBOX=(tb) $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /STRC=fs /NWOK
839                        break
840                endif
841               
842                if(useResol)            //res only
843//                      Print "timing test for Cylinder_PolyRadius---"
844//                      Variable t0 = stopMStimer(-2)
845
846                        FuncFit/H=getHStr(hold) /M=2 /NTHR=0 $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /STRC=fs /NWOK
847                       
848//                      t0 = (stopMSTimer(-2) - t0)*1e-6
849//                      Printf  "CylPolyRad fit time using res and eps and /NTHR=0 time = %g seconds\r\r",t0
850//                      cw[0] = .01
851//                      cw[1] = 20
852//                      cw[2] = 400
853//                      cw[3] = 0.2
854//                      cw[4] = 3e-6
855//                      cw[5] = 0.0
856//                     
857//                      t0 = stopMSTimer(-2)
858//                      FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /STRC=fs /NWOK
859//                      t0 = (stopMSTimer(-2) - t0)*1e-6
860//                      Printf  "CylPolyRad fit time using res and eps and NO THREADING time = %g seconds\r\r",t0
861                        break
862                endif
863                       
864               
865               
866/////   same as above, but all without useResol (no /STRC flag)
867                if(useResiduals && useTextBox)          //resid+ text
868                        FuncFit/H=getHStr(hold) /M=2 /NTHR=0 /TBOX=(tb) $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /R /NWOK
869                        break
870                endif
871               
872                if(useResiduals)                //resid
873                        FuncFit/H=getHStr(hold) /M=2 /NTHR=0 $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /R /NWOK
874                        break
875                endif
876
877               
878                if(useTextBox)          //text
879                        FuncFit/H=getHStr(hold) /M=2 /NTHR=0 /TBOX=(tb) $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /NWOK
880                        break
881                endif
882               
883                //just a plain vanilla fit
884
885                FuncFit/H=getHStr(hold) /M=2 /NTHR=0 $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /NWOK
886               
887        while(0)
888       
889        t0 = (stopMSTimer(-2) - t0)*1e-6
890        Printf  "fit time = %g seconds\r\r",t0
891       
892       
893        // append the fit
894        // need to manage duplicate copies
895        // Don't plot the full curve if cursors were used (set fitYw to NaN on entry...)
896        String traces=TraceNameList("", ";", 1 )                //"" as first parameter == look on the target graph
897        if(strsearch(traces,"FitYw",0) == -1 )
898                if(useGenCurveFit && useCursors)
899                        WAVE trimX = trimX
900                        AppendtoGraph fitYw vs trimX
901                else
902                        AppendToGraph FitYw vs xw
903                endif
904        elseif (strsearch(traces,"FitYw_RA",0) == -1)
905                RemoveFromGraph FitYw
906                if(useGenCurveFit && useCursors)
907                        WAVE trimX = trimX
908                        AppendtoGraph fitYw vs trimX
909                else
910                        AppendToGraph FitYw vs xw
911                endif
912        else
913                RemoveFromGraph FitYw_RA
914                if(useGenCurveFit && useCursors)
915                        WAVE trimX = trimX
916                        AppendtoGraph fitYw vs trimX
917                else
918                        AppendToGraph FitYw vs xw
919                endif
920        endif
921        ModifyGraph lsize(FitYw)=2,rgb(FitYw)=(0,0,0)
922       
923        DoUpdate                //force update of table and graph with fitted values (why doesn't this work? - the table still does not update)
924       
925        // report the results (to the panel?)
926        if(useGenCurveFit)
927                V_chisq = chi
928                V_npnts = pt
929        endif
930        print "V_chisq = ",V_chisq
931        print cw
932        WAVE/Z w_sigma
933        print w_sigma
934        String resultStr=""
935        Variable maxRelError=0
936       
937        if(waveexists(W_sigma))
938                //append it to the table, if it's not already there
939                CheckDisplayed/W=WrapperPanel#T0 W_sigma
940                if(V_flag==0)
941                        //not there, append it
942                        AppendtoTable/W=wrapperPanel#T0 W_sigma
943                else
944                        //remove it, and put it back on to make sure it's the right one (do I need to do this?)
945                        // -- not really, since any switch of the function menu takes W_Sigma off
946                endif
947                // then do I want to color it if the errors are horrible?
948                Duplicate/O cw, relError
949                relError = W_sigma/cw
950                maxRelError = WaveMax(relError)
951                if(maxRelError > kRelErrorTolerance)
952                        ModifyTable/W=wrapperPanel#T0 style(W_sigma)=1,rgb(W_sigma)=(65535,0,0)
953                else
954                        ModifyTable/W=wrapperPanel#T0 style=0,rgb=(0,0,0)
955        endif
956       
957        endif
958       
959        //now re-write the results
960        sprintf resultStr,"Chi^2 = %g  Sqrt(X^2/N) = %g",V_chisq,sqrt(V_chisq/V_Npnts)
961        resultStr = PadString(resultStr,63,0x20)
962        DoWIndow/F WrapperPanel
963        GroupBox grpBox_2 title=resultStr
964        ControlUpdate/W=WrapperPanel grpBox_2
965        sprintf resultStr,"FitErr = %s : FitQuit = %s",W_ErrorMessage(V_FitError),W_QuitMessage(V_FitQuitReason)
966        resultStr = PadString(resultStr,63,0x20)
967        GroupBox grpBox_3 title=resultStr
968        ControlUpdate/W=WrapperPanel grpBox_3
969       
970        Variable yesSave=0,yesReport=0
971        ControlInfo/W=WrapperPanel check_4
972        yesReport = V_Value
973        ControlInfo/W=WrapperPanel check_5
974        yesSave = V_Value
975       
976       
977        if(yesReport)
978                String parStr=GetWavesDataFolder(cw,1)+ WaveList("*param*"+"_"+suffix, "", "TEXT:1," )          // this is *hopefully* one wave
979                String topGraph= WinName(0,1)   //this is the topmost graph
980       
981                DoUpdate                //force an update of the graph before making a copy of it for the report
982
983                //if GenCurveFit used, V_startRow and V_endRow may not exist - so read the cursors? but the cursors may not be used, so
984                // there won't be anything on the graph... but pt1 and pt2 are set and passed!. The V_ variables are more foolproof
985                // so keep these for the "normal" report
986                //
987                if(useGenCurveFit)     
988                        W_GenerateReport(funcStr,folderStr,$parStr,cw,yesSave,V_chisq,W_sigma,V_npnts,V_FitError,V_FitQuitReason,pt1,pt2,topGraph)
989                else
990                        W_GenerateReport(funcStr,folderStr,$parStr,cw,yesSave,V_chisq,W_sigma,V_npnts,V_FitError,V_FitQuitReason,V_startRow,V_endRow,topGraph)
991                endif
992        endif
993       
994        //Rescale the Plot depending on the user choice
995        if(useRescaleAxis)
996                string ctrlName = "GoRescale"
997                RescalePlot(ctrlName)
998        elseif (DataFolderExists("root:Packages:NIST:RescaleAxis"))
999                SetDataFolder root:
1000                String PlotGraph= WinName(0,1)  //this is the topmost graph
1001                DoWindow/F $PlotGraph
1002               
1003                GetWindow/Z $PlotGraph, wavelist
1004                if (V_flag != 0)
1005                        DoPrompt/Help="" "I couldn't find the graph"
1006                        Abort
1007                endif
1008               
1009                wave/t W_Wavelist
1010               
1011                variable j
1012                string temp
1013                SetDataFolder root:Packages:NIST:RescaleAxis
1014                if (exists("W_WaveList")==1)
1015                        KillWaves/Z root:Packages:NIST:RescaleAxis:W_WaveList
1016                endif
1017                MoveWave root:W_WaveList, root:Packages:NIST:RescaleAxis:W_WaveList
1018               
1019                for(i=0; i < numpnts(W_Wavelist)/3; i+=1)
1020                        temp = W_WaveList[i][0]
1021                        if(stringmatch(temp, "*_RA"))
1022               
1023                                string WaveDataFolder, WaveToRescale
1024                                WaveDataFolder = ReplaceString(W_WaveList[i][0], W_WaveList[i][1], "")
1025                                if(strlen(WaveDataFolder)==0)
1026                                        WaveDataFolder = ":"
1027                                endif
1028                                WaveDataFolder = "root"+WaveDataFolder 
1029                                SetDataFolder $WaveDataFolder
1030                                temp = RemoveEnding(temp, "_RA")
1031                               
1032                                string xwave, ywave, oldywave, swave
1033                                if(exists(temp)==1)
1034                                        Wave/T WaveString = $temp
1035                                        WaveToRescale = temp
1036                                        if (stringmatch(WaveToRescale, "*_i"))
1037                                                DoWindow/F PlotGraph
1038                                                oldywave = WaveToRescale+"_RA"
1039                                                ywave = WaveToRescale
1040                                                replacewave/Y/W=$PlotGraph trace=$oldywave, $ywave
1041                                                xwave = RemoveEnding(WaveToRescale, "_i")+"_q"
1042                                                replacewave/X/W=$PlotGraph trace=$ywave, $xwave
1043                                                ModifyGraph log=0
1044                                                swave = RemoveEnding(WaveToRescale, "_i")+"_s"
1045                                                if(exists(swave)==1)
1046                                                        ErrorBars/W=$PlotGraph $ywave, Y wave=($swave,$swave)   
1047                                                endif
1048                                        elseif(stringmatch(WaveToRescale, "smeared*") && stringmatch(WaveToRescale, "!*_qvals"))
1049                                                oldywave = WaveToRescale+"_RA"
1050                                                ywave = WaveToRescale
1051                                                replacewave/Y/W=$PlotGraph trace=$oldywave, $ywave
1052                                                xwave = "smeared_qvals"
1053                                                replacewave/X/W=$PlotGraph trace=$ywave, $xwave
1054                                                ModifyGraph log=0
1055                                        elseif(stringmatch(WaveToRescale,"ywave*"))
1056                                                oldywave = WaveToRescale+"_RA"
1057                                                ywave = WaveToRescale
1058                                                xwave = ReplaceString("ywave",ywave,"xwave")
1059                                                replacewave/Y/W=$PlotGraph trace=$oldywave, $ywave
1060                                                replacewave/X/W=$PlotGraph trace=$ywave, $xwave                                 
1061                                        endif
1062                                SetDataFolder root:Packages:NIST:RescaleAxis
1063                                endif
1064                        endif
1065                endfor
1066                KillWaves/Z W_WaveList
1067                modifygraph log=1
1068                Label left "I(q)"
1069                Label bottom "q (A\S-1\M)"
1070        Endif
1071
1072        SetDataFolder root:
1073        return(0)
1074End
1075
1076// parse something off of a table, or ?
1077Function/S getHStr(hold)
1078        Wave hold
1079       
1080        String str=""
1081        Variable ii
1082        for(ii=0;ii<numpnts(hold);ii+=1)
1083                str += num2str(hold[ii])
1084        endfor
1085
1086//      print str
1087        if(strsearch(str, "1", 0) == -1)
1088                return ("")
1089        else
1090                return(str)
1091        endif
1092End
1093
1094//taken from SRK Auto_Fit, and modified to work better with FitWrapper
1095//must have AutoGraph as the name of the graph window (any size)
1096// func is the name of the function (for print only)
1097//par and coef are the exact names of the waves
1098//yesSave==1 will save the file(name=func+time)
1099//
1100Function W_GenerateReport(func,dataname,param,ans,yesSave,chiSq,sigWave,npts,fitErr,fitQuit,fitStart,fitEnd,topGraph)
1101        String func,dataname
1102        Wave/T param
1103        Wave ans
1104        Variable yesSave,chiSq
1105        Wave sigWave
1106        Variable npts,fitErr,fitQuit,fitStart,fitEnd
1107        String topGraph
1108       
1109        String str,pictStr="P_"
1110        String nb="Report"
1111               
1112        // bring report up
1113        DoWindow/F Report
1114        if (V_flag == 0)                // Report notebook doesn't exist ?
1115                NewNotebook/W=(10,45,550,620)/F=1/N=Report as "Report"
1116        endif
1117        // delete old stuff
1118        Notebook $nb selection={startOfFile, endOfFile}, text="\r", selection={startOfFile, startOfFile}
1119       
1120        //setup
1121        Notebook $nb defaultTab=36, statusWidth=252, pageMargins={72,72,72,72}
1122        Notebook $nb showRuler=1, rulerUnits=1, updating={1, 60}
1123        Notebook $nb newRuler=Normal, justification=0, margins={0,0,468}, spacing={0,0,0}, tabs={}, rulerDefaults={"Geneva",10,0,(0,0,0)}
1124//     
1125        // insert title
1126        Notebook $nb newRuler=Title, justification=1, rulerDefaults={"Times", 16, 1, (0, 0, 0)}
1127        sprintf str, "Fit to %s, %s, %s\r\r", func,Secs2Date(datetime, 0), time()
1128        Notebook $nb ruler=Title, text=str
1129       
1130        // insert fit results
1131        Variable num=numpnts(ans),ii=0
1132        Notebook $nb ruler=Normal
1133        Notebook $nb  margins={18,18,504}, tabs={63 + 3*8192}
1134        str = "Data file: " + dataname + "\r\r"
1135        Notebook $nb text=str
1136        Notebook $nb ruler=Normal
1137        Notebook $nb margins={18,18,504}, tabs={144,234,252}
1138        do
1139                sprintf str, "%s = \t%g\t±\t%g\r", param[ii],ans[ii],sigwave[ii]
1140                Notebook $nb text=str
1141                ii+=1
1142        while(ii<num)
1143       
1144        //
1145        // no "fitted range" for 2D data, so make sure that this exists before using it
1146        Wave/Z dataXw = $("root:"+dataname+":"+dataname+"_q")   
1147        //
1148        Notebook $nb ruler=Normal
1149        Notebook $nb  margins={18,18,504}, tabs={63+3*8192}, fStyle=1, textRGB=(65000,0,0)
1150       
1151        sprintf str,"chisq = %g\r",chisq
1152        Notebook $nb textRGB=(65000,0,0),fstyle=1,text=str
1153        sprintf str,"Npnts = %g \t\t Sqrt(X^2/N) = %g\r",npts,sqrt(chiSq/npts)
1154        Notebook $nb textRGB=(0,0,0),fstyle=0, text=str
1155        if(WaveExists(dataXw))
1156                sprintf str "Fitted range = [%d,%d] = %g < Q < %g\r",fitStart,fitEnd,dataXw(fitStart),dataXw(fitEnd)
1157                Notebook $nb textRGB=(0,0,0),fstyle=0, text=str
1158        endif
1159        sprintf str,"FitError = %s\t\tFitQuitReason = %s\r",W_ErrorMessage(FitErr),W_QuitMessage(FitQuit)
1160        Notebook $nb textRGB=(65000,0,0),fstyle=1,text=str
1161        Notebook $nb ruler=Normal
1162       
1163        // insert graphs
1164        if(WaveExists(dataXw))
1165//              Notebook $nb picture={$topGraph(0, 0, 400, 300), -5, 1}, text="\r"
1166                Notebook $nb scaling={50, 50}, picture={$topGraph(0, 0, 800, 600), -5, 1}, text="\r"
1167        //
1168        else            //must be 2D Gizmo
1169                Execute "ExportGizmo Clip"                      //this ALWAYS is a PICT or BMP. Gizmo windows are different...
1170                LoadPict/Q/O "Clipboard",tmp_Gizmo
1171                Notebook $nb picture={tmp_Gizmo(0, 0, 800, 600), 0, 1}, text="\r"
1172        endif
1173       
1174        // show the top of the report
1175        Notebook $nb  selection= {startOfFile, startOfFile},  findText={"", 1}
1176       
1177        //save the notebook and the graphic file
1178        // saving with a unique name can be an issue if there are a lot of files with similar names
1179        // and the fit function has a long name
1180        if(yesSave)
1181                String nameStr
1182                // function first               
1183//              nameStr=CleanupName(func,0)
1184//              nameStr += "_"+dataname
1185//              nameStr = ReplaceString("Smeared",nameStr,"Sm_")                //if Smeared function, shorten the name
1186                // -- or
1187                // data first
1188                nameStr = dataname+"_"
1189                nameStr += CleanupName(func,0)
1190                nameStr = ReplaceString("Smeared",nameStr,"Sm_")                //if Smeared function, shorten the name
1191
1192                //make sure the name is no more than 31 characters
1193                namestr = namestr[0,30]         //if shorter than 31, this will NOT pad to 31 characters
1194               
1195                Print "file saved as ",nameStr
1196                SaveNotebook /O/P=home/S=2 $nb as nameStr
1197                //save the graph separately as a PNG file, 2x screen
1198                pictStr += nameStr
1199                pictStr = pictStr[0,24]+".png"          //need a shorter name - only 29 characters allowed - why?
1200//              DoWindow/F $topGraph
1201                // E=-5 is png @screen resolution
1202                // E=2 is PICT @2x screen resolution
1203///             SavePICT /E=-5/O/P=home /I/W=(0,0,3,3) as pictStr
1204                if(WaveExists(dataXw))
1205                        SavePICT /E=-5/O/P=home/WIN=$topGraph /W=(0,0,800,600) as pictStr
1206                else
1207                        Execute "ExportGizmo /P=home as \""+pictStr+"\""                //this won't be of very high quality
1208                        //SavePICT /E=-5/O/P=home/WIN=$topGraph /W=(0,0,400,300) as pictStr
1209                endif
1210        Endif
1211       
1212        // ???maybe print the notebook too?
1213End
1214
1215Function/S W_ErrorMessage(code)
1216        Variable code
1217       
1218        switch (code)
1219                case 0:
1220                        return "No Error"
1221                        break
1222                case 3: //2^0 + 2^1
1223                        return "Singular Matrix"
1224                        break
1225                case 5:         //(2^0 + 2^2)
1226                        return "Out of Memory"
1227                        break
1228                case 9:         //(2^0 + 2^3)
1229                        return "Func= NaN or Inf"
1230                        break
1231                default:
1232                        return "Unknown error code "+num2str(code)
1233        endswitch
1234end
1235
1236Function/S W_QuitMessage(code)
1237        Variable code
1238       
1239        switch (code)
1240                case 0:
1241                        return "No Error"
1242                        break
1243                case 1:
1244                        return "Max iterations - re-run fit"
1245                        break
1246                case 2:
1247                        return "User terminated fit"
1248                        break
1249                case 3:
1250                        return "No decrease in chi-squared"
1251                        break
1252                default:
1253                        return "Unknown Quit code "+num2str(code)
1254        endswitch
1255end
1256
1257Function UseInfoTextBoxCheckProc(cba) : CheckBoxControl
1258        STRUCT WMCheckboxAction &cba
1259
1260        switch( cba.eventCode )
1261                case 2: // mouse up
1262                        Variable checked = cba.checked
1263                        if(checked)
1264                                //print "checked, use textBox in the next fit"
1265                        else
1266                                //print "unchecked, ask to remove TextBox from the graph"
1267                                ControlInfo/W=WrapperPanel popup_0
1268                                RemoveTextBox(S_value)
1269                        endif
1270                        break
1271        endswitch
1272
1273        return 0
1274End
1275
1276//does not report an error if the text box is not there
1277// -- so I'll just be lazy and not check to see if it's there
1278//
1279Function RemoveTextBox(folderStr)
1280        String folderStr
1281       
1282        DoAlert 1,"Remove the TextBox from the graph?"
1283        if(V_flag == 1)
1284                String str = "CF_"+folderStr+"_i"
1285                TextBox/K/N=$str
1286        endif
1287        return(0)
1288End
1289
1290Function UseResidualsCheckProc(cba) : CheckBoxControl
1291        STRUCT WMCheckboxAction &cba
1292
1293        switch( cba.eventCode )
1294                case 2: // mouse up
1295                        Variable checked = cba.checked
1296                        if(checked)
1297                                //print "checked, use them in the next fit"
1298                        else
1299                                //print "unchecked, ask to remove residuals from the graph"
1300                                ControlInfo/W=WrapperPanel popup_0
1301                                RemoveResiduals(S_value)
1302                        endif
1303                        break
1304        endswitch
1305
1306        return 0
1307End
1308
1309// the default name from the /R flag is "Res_" + yWaveName
1310//
1311// better to find the wave that starts with "Res_" and remove that one in case the
1312// wave names get too long
1313//
1314// the difficulty now is that the residual wave ends up in root: and not with the data....
1315// -- not really a problem, but adds to clutter
1316Function RemoveResiduals(folderStr)
1317        String folderStr
1318       
1319        String list="",topWin=""
1320        Variable num,ii
1321        String str
1322
1323        DoAlert 1,"Remove the residuals from the graph?"
1324        if(V_flag == 1)
1325//              String topGraph= WinName(0,1)   //this is the topmost graph
1326                list=TraceNameList("", ";", 1 )         //"" as first parameter == look on the target graph
1327                num=ItemsInList(list)
1328               
1329                for(ii=0;ii<num;ii+=1)
1330                        str = StringFromList(ii, list ,";")
1331                        if(strsearch(str, "Res_", 0) != -1)
1332                                RemoveFromGraph $str
1333                        endif
1334                endfor
1335       
1336                SetDataFolder root:
1337        endif
1338       
1339        return(0)
1340End
1341
1342Function Toggle2DControlsCheckProc(cba) : CheckBoxControl
1343        STRUCT WMCheckboxAction &cba
1344
1345        switch( cba.eventCode )
1346                case 2: // mouse up
1347                        Variable checked = cba.checked
1348                        if(checked)
1349                                //print "change the buttons to 2D"
1350                                Button button_0,proc=Do2DFitButtonProc,title="Do 2D Fit"
1351                                Button button_1,size={120,20},proc=Plot2DFunctionButtonProc,title="Plot 2D Function"
1352                                Button button_2,size={100,20},proc=Append2DModelButtonProc,title="Append 2D"
1353                                Button button_3,size={100,20},proc=Load2DDataButtonProc,title="Load 2D Data"
1354                               
1355                                Button button_2D_0,pos={550,60},size={70,20},proc=LogToggle2DButtonProc,title="Log/Lin"
1356                                Button button_2D_1,pos={520,37},size={100,20},proc=Plot2DButtonProc,title="Plot 2D Data"
1357                               
1358                                Button button_2D_0,disable=0            //visible again, and enabled
1359                                Button button_2D_1,disable=0
1360                               
1361                                CheckBox check_6,disable=1                      //info box and residual check, remove these from view
1362                                CheckBox check_7,disable=1
1363                                CheckBox check_8,disable=1
1364                        else
1365                                //print "unchecked, change them back to 1D"
1366                                Button button_0,pos={520,93},size={100,20},proc=DoTheFitButton,title="Do 1D Fit"
1367                                Button button_1,pos={280,57},size={120,20},proc=PlotModelFunction,title="Plot 1D Function"
1368                                Button button_2,pos={300,93},size={100,20},proc=AppendModelToTarget,title="Append 1D"
1369                                Button button_3,pos={300,20},size={100,20},proc=W_LoadDataButtonProc,title="Load 1D Data"
1370                               
1371                                Button button_2D_0,disable=3    //hide the extra 2D buttons, and disable
1372                                Button button_2D_1,disable=3
1373                               
1374                                CheckBox check_6,disable=0                      //info box and residual check, bring them back
1375                                CheckBox check_7,disable=0
1376                                CheckBox check_8,disable=0
1377                        endif
1378                        break
1379        endswitch
1380
1381        return 0
1382End
1383
1384// function to either add or remove the cursors from the topmost graph, as needed
1385
1386Function UseCursorsWrapperProc(cba) : CheckBoxControl
1387        STRUCT WMCheckboxAction &cba
1388
1389
1390        switch( cba.eventCode )
1391                case 2: // mouse up
1392               
1393                        // check to make sure there really is a "topmost" graph         
1394                        String topGraph= WinName(0,1)   //this is the topmost graph
1395                        if(cmpstr(topGraph,"")==0)      //no graphs, uncheck and exit
1396                                CheckBox check_0,value=0
1397                                return(0)
1398                        endif
1399                       
1400                        //if in 2D mode, just exit
1401                        ControlInfo/W=WrapperPanel check_3
1402                        if(V_Value == 1)
1403                                return (0)
1404                        endif
1405                               
1406                        String ciStr = CsrInfo(A , topGraph)
1407                       
1408                        ControlInfo/W=wrapperpanel popup_0
1409                        String folderStr=S_Value
1410                        String traceList = TraceNameList(topGraph, ";", 1 )             
1411               
1412                        Variable checked = cba.checked
1413                       
1414                        if(checked)
1415                                //print "add the cursors to the topmost graph, if the data set is there, or move them"
1416                                if(strlen(ciStr)==0 && strsearch(traceList, folderStr, 0) != -1 )               //no cursors && data is there
1417                                        ShowInfo
1418                                        Wave yw=$("root:"+folderStr+":"+folderStr+"_i")
1419                                        Cursor/P/W=$topGraph A, $(folderStr+"_i"),0
1420                                        Cursor/P/W=$topGraph/A=0 B, $(folderStr+"_i"),numpnts(yw)-1                     //deactivate the one at the high Q end
1421                                        DoUpdate
1422                                elseif (strlen(ciStr)!=0 && strsearch(traceList, folderStr, 0) != -1 ) //cursors present, but on wrong data
1423                                        Wave yw=$("root:"+folderStr+":"+folderStr+"_i")
1424                                        Cursor/P/W=$topGraph A, $(folderStr+"_i"),0                                                             //move the cursors
1425                                        Cursor/P/W=$topGraph/A=0 B, $(folderStr+"_i"),numpnts(yw)-1
1426                                        DoUpdate
1427                                endif
1428                               
1429                                AreCursorsCorrect(folderStr)
1430                        else
1431                                //print "unchecked, remove the cursors"
1432                                // go back to the full matrix for the resolution calculation (not if SANS data...)
1433                                if(waveExists($("root:"+folderStr+":weights_save")))
1434                                        Duplicate/O $("root:"+folderStr+":weights_save"), $("root:"+folderStr+":"+folderStr+"_res"),$("root:"+folderStr+":"+folderStr+"_rest")
1435                                endif
1436
1437                                HideInfo/W=$topGraph
1438                                Cursor/K A
1439                                Cursor/K B
1440                        endif
1441                        break
1442        endswitch
1443
1444        return 0
1445End
1446
1447// returns 1 if the specified data is on the top graph && has cursors on it
1448// returns 0 and unchecks the box if anything is wrong
1449//
1450// only call this function if the cursor box is checked, to uncheck it as needed
1451// if the box is unchecked, leave it be.
1452//
1453Function AreCursorsCorrect(folderStr)
1454        String folderStr
1455       
1456        String topGraph= WinName(0,1)   //this is the topmost graph
1457        if(cmpstr(topGraph,"")==0)      //no graphs, uncheck and exit
1458                CheckBox check_0,win=wrapperpanel,value=0
1459                return(0)
1460        endif
1461               
1462        String traceAisOn = CsrWave(A , "", 0)
1463        if(     strsearch(traceAisOn, folderStr, 0) == -1)              //data and cursors don't match
1464                CheckBox check_0,win=wrapperpanel,value=0
1465                HideInfo
1466                Cursor/K A
1467                Cursor/K B
1468                return(0)
1469        endif
1470       
1471        return(1)
1472End
1473
1474
1475
1476//////////////////////////////
1477//
1478// displays the covariance matrix for the current data set in the popup
1479// AND whatever was the last fit for that data set. it may not necessarily
1480// be the displayed function...
1481Function DisplayCovarianceMatrix()
1482
1483       
1484
1485        ControlInfo/W=wrapperpanel popup_0
1486        String folderStr=S_Value
1487
1488        ControlInfo/W=WrapperPanel popup_1
1489        String funcStr=S_Value
1490                       
1491        if(Stringmatch(funcStr,"Smear*"))               //simple test for smeared function
1492                if(DataFolderExists("root:"+folderStr))
1493                        SetDataFolder $("root:"+folderStr)
1494                else
1495                        SetDataFolder root:
1496                endif
1497        else
1498                SetDataFolder root:
1499        endif
1500       
1501        Wave M_Covar=M_Covar
1502        Duplicate/O M_Covar, CorMat      // You can use any name instead of CorMat
1503        CorMat = M_Covar[p][q]/sqrt(M_Covar[p][p]*M_Covar[q][q])
1504
1505        // clear the table (a subwindow)
1506        DoWindow/F CorMatPanel                          // ?? had to add this in during all of the cursor meddling...
1507        KillWindow CorMatPanel#T0
1508        Edit/W=(20,74,634,335)/HOST=CorMatPanel
1509        RenameWindow #,T0
1510        // get them onto the table
1511        // how do I get the parameter name?
1512        String param = getFunctionParams(funcStr)
1513        AppendtoTable/W=CorMatPanel#T0 $param
1514        AppendToTable/W=CorMatPanel#T0 CorMat
1515        ModifyTable/W=CorMatPanel#T0 width(Point)=0
1516
1517        GroupBox grpBox_1 title="Data set: "+folderStr
1518        GroupBox grpBox_2 title="Function: "+funcStr
1519
1520
1521        SetDataFolder root:
1522       
1523        return(0)
1524End
1525
1526
1527Window CorMatPanel()
1528        PauseUpdate; Silent 1           // building window...
1529        NewPanel /W=(459,44,1113,399)/N=CorMatPanel/K=1 as "Correlation Matrix"
1530        ModifyPanel fixedSize=1
1531       
1532        GroupBox grpBox_1 title="box 1",pos={10,20},size={0,0},frame=1,fSize=10,fstyle=1,fColor=(39321,1,1)
1533        GroupBox grpBox_2 title="box 2",pos={10,40},size={0,0},frame=1,fSize=10,fstyle=1,fColor=(39321,1,1)
1534
1535        Button button_1,pos={520,30},size={100,20},proc=CorMatHelpButtonProc,title="Help"
1536
1537        Edit/W=(20,74,634,335)/HOST=# 
1538        ModifyTable width(Point)=0
1539        RenameWindow #,T0
1540        SetActiveSubwindow ##
1541EndMacro
1542
1543
1544Proc DisplayCovariance()
1545        DoWindow/F CorMatPanel
1546        if(V_Flag==0)
1547                CorMatPanel()
1548        endif
1549       
1550        DisplayCovarianceMatrix()
1551
1552End
1553
1554//open the Help file for the Fit Manager
1555Function CorMatHelpButtonProc(ba) : ButtonControl
1556        STRUCT WMButtonAction &ba
1557
1558        switch( ba.eventCode )
1559                case 2: // mouse up
1560                        // click code here
1561                        DisplayHelpTopic/Z/K=1 "Covariance Matrix"
1562                        if(V_flag !=0)
1563                                DoAlert 0,"Help for the correlation matrix could not be found"
1564                        endif
1565                        break
1566        endswitch
1567
1568        return 0
1569End
1570
1571
1572//////////////////////////////////
1573// this is a snippet from Andy Nelson, posted at the Igor Exchange web site.
1574//
1575// search area appears to be a percent (so enter 10 to get +/- 10% variation in the parameter)
1576//
1577// TODO:
1578//              x- rename the function for just me
1579//              x- make the edata a mandatory parameter
1580//              x- remove rhs, lhs? or keep these if cursors were used to properly trim the data set
1581//              x- label the graph
1582//              x- make a panel to control this - to either pick a single parameter, or show all of them
1583//              x- have it re-use the same graph, not draw a (new) duplicate one
1584//              x- update it to use the AAO as the input function (new func template -- see Gauss Utils)
1585//              x- the wrapper must be data folder aware, and data set aware like in the Wrapper panel
1586//              x- need a different wrapper for smeared and unsmeared functions
1587//
1588//
1589
1590
1591
1592Proc MapChiSquared(paramNum,percent)
1593        Variable paramNum=0,percent=10
1594        Prompt paramNum, "Enter parameter number: "
1595        Prompt percent, "Enter percent variation +/- : "
1596
1597        fChiMap(paramNum,percent)
1598End
1599
1600
1601// this does the math for a single value of "whichParam"
1602Function chi2gen(funcStr,folderStr,xw,yw,sw,cw,whichParam,searchArea,lhs,rhs,useResol)
1603        String funcStr,folderStr
1604        Wave xw,yw,sw,cw      //        x data, y data, error wave, and coefficient wave
1605        variable whichParam, searchArea  //which of the parameters to you want to vary, how far from the original value do you want to search (%)
1606        variable lhs, rhs    //specify a region of interest in the data using a left hand side and right hand side.
1607        variable useResol               // =1 if smeared used
1608 
1609        variable originalvalue = cw[whichparam]
1610        variable range = originalValue * searchArea/100
1611        variable ii,err
1612 
1613        duplicate/o yw, :theoretical_data, :chi2_data
1614        Wave theoretical_data, chi2_data
1615 
1616        make/o/n=200/d chi2_map
1617        setscale/I x,  originalvalue - range/2, originalvalue + range/2, chi2_map
1618 
1619        String DF="root:"+folderStr+":"
1620        String suffix=getModelSuffix(funcStr)
1621
1622        // fill a struct instance whether it is needed or not
1623        Struct ResSmearAAOStruct fs
1624        WAVE/Z resW = $(DF+folderStr+"_res")                    //these may not exist, if 3-column data is used
1625        WAVE/Z fs.resW =  resW
1626//              WAVE yw=$(DF+folderStr+"_i")
1627//              WAVE xw=$(DF+folderStr+"_q")
1628//              WAVE sw=$(DF+folderStr+"_s")
1629        Wave fs.coefW = cw
1630        Wave fs.yW = theoretical_data
1631        Wave fs.xW = xw
1632 
1633 
1634 
1635        for(ii=0 ; ii < numpnts(chi2_map) ; ii+=1)
1636                cw[whichparam] = pnt2x(chi2_map, ii)
1637 
1638                if(useResol)
1639                        FUNCREF SANSModelSTRUCT_proto func1=$funcStr
1640                        err = func1(fs)
1641                else
1642                        FUNCREF SANSModelAAO_proto func2=$funcStr
1643                        func2(cw,theoretical_data,xw)
1644                endif
1645               
1646                chi2_data = (yw-theoretical_data)^2
1647 
1648                chi2_data /= sw^2
1649
1650                Wavestats/q/R=[lhs, rhs] chi2_data
1651 
1652                chi2_map[ii] = V_avg * V_npnts
1653        endfor
1654 
1655        cw[whichparam] = originalvalue
1656 
1657        DoWindow/F Chi2
1658        if(V_flag==0)
1659                display/K=1/N=Chi2 chi2_map
1660                Label left "Chi^2"
1661        endif
1662
1663        String parStr=GetWavesDataFolder(cw,1)+ WaveList("*param*"+"_"+suffix, "", "TEXT:1," )          // this is *hopefully* one wave
1664        Wave/T parW = $parStr
1665        Label bottom parW[whichParam]
1666       
1667       
1668        killwaves/z theoretical_data, chi2_data
1669End
1670 
1671
1672// this does the setup
1673Function fChiMap(paramNum,percent)
1674        Variable paramNum,percent
1675
1676        String folderStr,funcStr,coefStr
1677        Variable useCursors,useResol=0,pt1,pt2
1678       
1679        ControlInfo/W=WrapperPanel popup_0
1680        folderStr=S_Value
1681       
1682        ControlInfo/W=WrapperPanel popup_1
1683        funcStr=S_Value
1684       
1685        ControlInfo/W=WrapperPanel popup_2
1686        coefStr=S_Value
1687       
1688        ControlInfo/W=WrapperPanel check_0
1689        useCursors=V_Value
1690       
1691       
1692// first, figure out where we are...
1693        String suffix=getModelSuffix(funcStr)
1694       
1695        SetDataFolder $("root:"+folderStr)
1696        if(!exists(coefStr))
1697                // must be unsmeared model, work in the root folder
1698                SetDataFolder root:                             
1699                if(!exists(coefStr))            //this should be fine if the coef filter is working, but check anyhow
1700                        DoAlert 0,"the coefficient and data sets do not match"
1701                        return 0
1702                endif
1703        endif
1704               
1705        WAVE cw=$(coefStr)
1706
1707
1708// test for smeared function
1709        if(stringmatch(funcStr, "Smear*"))              // if it's a smeared function, need a struct
1710                useResol=1
1711        endif
1712       
1713        // fill a struct instance whether I need one or not
1714        String DF="root:"+folderStr+":"
1715       
1716//      Struct ResSmearAAOStruct fs
1717//      WAVE/Z resW = $(DF+folderStr+"_res")                    //these may not exist, if 3-column data is used
1718//      WAVE/Z fs.resW =  resW
1719        WAVE yw=$(DF+folderStr+"_i")
1720        WAVE xw=$(DF+folderStr+"_q")
1721        WAVE sw=$(DF+folderStr+"_s")
1722//      Wave fs.coefW = cw
1723//      Wave fs.yW = yw
1724//      Wave fs.xW = xw
1725       
1726        if(useCursors)
1727                if(pcsr(A) > pcsr(B))
1728                        pt1 = pcsr(B)
1729                        pt2 = pcsr(A)
1730                else
1731                        pt1 = pcsr(A)
1732                        pt2 = pcsr(B)
1733                endif
1734        else
1735                //if cursors are not being used, find the first and last points of the data set, and pass them
1736                pt1 = 0
1737                pt2 = numpnts(yw)-1
1738        endif
1739       
1740               
1741       
1742        chi2gen(funcStr,folderStr,xw,yw,sw,cw,paramNum,percent,pt1,pt2,useResol)
1743       
1744
1745End
1746
1747////////////////////////////////////
1748// Modification from Matt Wasbrough to allow rescaling of the
1749// axes while plotting and fitting. allows export of the rescaled
1750// data and of the rescaled model
1751// Nov 2012
1752///
1753
1754Function UseRescaleAxisCheckProc(cba) : CheckBoxControl
1755        STRUCT WMCheckboxAction &cba
1756
1757        switch( cba.eventCode )
1758                case 2: // mouse up
1759                        Variable checked = cba.checked
1760                        if(checked)
1761                                Execute "OpenAxisPanel()"
1762                        else
1763                                if(exists("RescaleAxisPanel") !=0)
1764                                        DoWindow/K RescaleAxisPanel
1765                                endif
1766                        endif
1767                        break
1768        endswitch
1769
1770        return 0
1771End
1772
1773Proc OpenAxisPanel()
1774        If(WinType("RescaleAxisPanel") == 0)
1775                //create the necessary data folder
1776                NewDataFolder/O root:Packages
1777                NewDataFolder/O root:Packages:NIST
1778                NewDataFolder/O root:Packages:NIST:RescaleAxis
1779                //initialize the values
1780                Variable/G root:Packages:NIST:RescaleAxis:gRAExpA = 1
1781                Variable/G root:Packages:NIST:RescaleAxis:gRAExpB = 1
1782                Variable/G root:Packages:NIST:RescaleAxis:gRAExpC = 1
1783                RescaleAxisPanel()
1784        else
1785                //window already exists, just bring to front for update
1786                DoWindow/F RescaleAxisPanel
1787        endif
1788End
1789
1790Window RescaleAxisPanel()
1791        PauseUpdate; Silent 1           // building window...
1792        NewPanel /W=(461,46,735,195)/K=1
1793        ModifyPanel cbRGB=(49360,30954,64507), fixedSize=1
1794        SetDrawLayer UserBack
1795        PopupMenu ymodel,pos={20,10},size={76,19},title="y-axis"
1796        PopupMenu ymodel,help={"This popup selects how the y-axis will be linearized based on the chosen data"}
1797        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)\""
1798        Button GoRescale,pos={50,80},size={70,20},proc=RescalePlot,title="Rescale"
1799        Button GoRescale,help={"This button will rescale the axis using the selections in this panel"}
1800        Button DoneButton,pos={170,80},size={70,20},proc=RADoneButton,title="Done"
1801        Button DoneButton,help={"This button will close the panel"}
1802        Button ExportData, pos={100,110}, size={90,20}, proc=ExportData, title="Export Data"
1803        Button ExportData, help={"This button will export data from the top graph"}
1804        SetVariable expa,pos={13,45},size={80,17},title="pow \"a\""
1805        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"}
1806        SetVariable expa,limits={-2,10,0},value= root:Packages:NIST:RescaleAxis:gRAExpA
1807        SetVariable expb,pos={98,45},size={80,17},title="pow \"b\""
1808        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"}
1809        SetVariable expb,limits={0,10,0},value= root:Packages:NIST:RescaleAxis:gRAExpB
1810        PopupMenu xmodel,pos={155,10},size={79,19},title="x-axis"
1811        PopupMenu xmodel,help={"This popup selects how the x-axis will be linearized given the chosen data"}
1812        PopupMenu xmodel,mode=1,value= #"\"q;log(q);q^2;q^c\""
1813        SetVariable expc,pos={182,45},size={80,17},title="pow \"c\""
1814        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"}
1815        SetVariable expc,limits={-10,10,0},value= root:Packages:NIST:RescaleAxis:gRAExpC
1816        Button RAHelp, pos={220,110}, size={20,20}, proc=RAHelpButtonProc, title="?"
1817EndMacro
1818
1819Proc RADoneButton(ctrlName): ButtonControl
1820        String ctrlName
1821        DoWindow/K RescaleAxisPanel
1822        DoWindow/F WrapperPanel
1823        CheckBox check_8 value=0
1824end
1825
1826Function RAHelpButtonProc(ba) : ButtonControl
1827        STRUCT WMButtonAction &ba
1828
1829        switch( ba.eventCode )
1830                case 2: // mouse up
1831                        // click code here
1832                        DisplayHelpTopic/Z/K=1 "Rescaled Axis"
1833                        if(V_flag !=0)
1834                                DoAlert 0,"The Rescaled Axis Help file could not be found"
1835                        endif
1836                        break
1837        endswitch
1838
1839        return 0
1840End
1841
1842Proc ExportData(ctrlName): ButtonControl
1843        string ctrlName
1844        WriteRescaledData()             
1845End
1846       
1847
1848Function RescalePlot (ctrlName): ButtonControl
1849        String ctrlName
1850        SetDataFolder root:
1851        String topGraph= WinName(0,1)   //this is the topmost graph
1852        if(strlen(topGraph)==0)
1853                Abort "There is no graph"
1854        endif
1855               
1856        DoWindow/F $topGraph
1857        GetWindow/Z $topGraph, wavelist
1858        wave/t W_Wavelist
1859        SetDataFolder root:Packages:NIST:RescaleAxis
1860        if (exists("W_WaveList")==1)
1861                KillWaves/Z root:Packages:NIST:RescaleAxis:W_WaveList
1862        endif
1863        MoveWave root:W_WaveList, root:Packages:NIST:RescaleAxis:W_WaveList
1864        SetDataFolder root:Packages:NIST:RescaleAxis
1865        variable i,j,k
1866        string DF,DF1,temp, temp2, t1
1867        for (i=0; i < numpnts(W_WaveList)/3; i+=1)
1868                temp = W_WaveList[i][1]
1869                if (stringmatch(temp, "*_i") || stringmatch(temp, "*_i_RA"))
1870                        temp = W_WaveList[i][0]
1871                        if(stringmatch(temp, "*_i"))
1872                                temp = removeending(temp, "_i")
1873                        elseif(stringmatch(temp, "*_i_RA"))
1874                                temp = removeending(temp, "_i_RA")
1875                        endif
1876                        Make/T/O $temp/Wave=tempWave
1877                        DF = ReplaceString(W_Wavelist[i][0],W_Wavelist[i][1],"")
1878                        if (strlen(DF) ==0)
1879                                DF = ":"
1880                        endif
1881                        DF1 = "root"+DF
1882                        tempWave[0] = DF1
1883                        k = 1
1884                        for(j=0;j<numpnts(W_WaveList)/3; j+=1)
1885                                if (stringmatch(W_WaveList[j][1], "*"+temp+"*"))
1886                                        tempWave[k] = W_WaveList[j][0]
1887                                        k  = k+1
1888                                endif
1889                        endfor
1890                        redimension/N=(k) tempWave
1891                elseif(stringmatch(temp, "*ywave*"))
1892                        temp = W_WaveList[i][0]
1893                        if(stringmatch(temp, "*_RA"))
1894                                temp = removeending(temp, "_RA")
1895                        endif                   
1896                        Make/T/O $temp/Wave=tempWave
1897                        DF = ReplaceString(W_Wavelist[i][0],W_Wavelist[i][1],"")
1898                        if (strlen(DF) ==0)
1899                                DF = ":"
1900                        endif
1901                        DF1 = "root"+DF
1902                        tempWave[0] = DF1
1903                        temp2 = replacestring("ywave", temp, "")
1904                        k = 1
1905                        for(j=0;j<numpnts(W_WaveList)/3; j+=1)
1906                                t1 = W_Wavelist[j][1]
1907                                if (stringmatch(W_WaveList[j][1], "*wave"+temp2+"*"))
1908                                        tempWave[k] = W_WaveList[j][1]
1909                                        k  = k+1
1910                                endif
1911                        endfor
1912                        redimension/N=(k) tempWave
1913                endif
1914        endfor
1915        KillWaves/Z W_Wavelist
1916        string listWave = Wavelist("*", ";", "TEXT:1")
1917        string WaveToRescale, WaveDataFolder,xwave, ywave, swave
1918       
1919        for (i = 0; i < ItemsInList(listWave,";"); i+=1)
1920                temp = StringFromList(i,listWave,";")
1921                Wave/T WaveString = $temp
1922                for (j=1; j < numpnts(WaveString); j+=1)
1923                         WaveToRescale = Wavestring[j]
1924                         if (stringmatch(WaveToRescale, "*_RA"))
1925                                WaveToRescale = RemoveEnding(WaveToRescale, "_RA")
1926                         endif
1927                WaveDataFolder = WaveString[0]
1928                SetDataFolder $WaveDataFolder
1929                if (stringmatch(WaveToRescale, "*_q"))
1930                xwave = WaveToRescale
1931                XRescale(xwave)
1932                elseif (stringmatch(WaveToRescale, "*_i"))
1933                ywave = WaveToRescale
1934                xwave = RemoveEnding(WaveToRescale, "_i")+"_q"
1935                YRescale(ywave, xwave)
1936                elseif (stringmatch(WaveToRescale, "*_s"))
1937                swave = WaveToRescale
1938                ywave = RemoveEnding(WaveToRescale, "_s")+"_i"
1939                xwave = RemoveEnding(WaveToRescale, "_s")+"_q"
1940                ERescale(swave, ywave, xwave)
1941                elseif (stringmatch(WaveToRescale, "xwave_*"))
1942                xwave=WaveToRescale
1943                XRescale(xwave)
1944                elseif (stringmatch(WaveToRescale, "ywave_*"))
1945                ywave = WaveToRescale
1946                xwave= ReplaceString("ywave", WaveToRescale, "xwave")
1947                YRescale(ywave, xwave)
1948                elseif(stringmatch(WaveToRescale, "*_qvals"))
1949                xwave = WaveToRescale
1950                XRescale(xwave)
1951                elseif(stringmatch(WaveToRescale, "smeared*") && stringmatch(WaveToRescale, "!*_qvals"))
1952                ywave = WaveToRescale
1953                                for (k=1; k < numpnts(WaveString); k+=1)
1954                                        if (stringmatch(Wavestring[k], "*_qvals"))
1955                                                xwave = Wavestring[k]
1956                                        endif
1957                                endfor
1958                YRescale(ywave, xwave)
1959                else
1960                ywave = WaveToRescale
1961                        for (k=1; k < numpnts(WaveString); k+=1)
1962                                if (stringmatch(Wavestring[k], "*_q"))
1963                                        xwave = Wavestring[k]
1964                                endif
1965                        endfor
1966                YRescale(ywave,xwave)
1967                string yAxis = ywave+"_RA"
1968                wave yAxisWave = $yAxis
1969                SetFormula yAxisWave, "YRescale(ywave,xwave)"
1970                endif
1971                SetDataFolder root:Packages:NIST:RescaleAxis
1972                endfor
1973        endfor
1974       
1975        string oldywave, xstr, ystr
1976        for (i = 0; i < ItemsInList(listWave,";"); i+=1)
1977                temp = StringFromList(i,listWave,";")
1978                Wave/T WaveString = $temp
1979                for (j=1; j < numpnts(WaveString); j+=1)
1980                         WaveToRescale = Wavestring[j]
1981                WaveDataFolder = WaveString[0]
1982                SetDataFolder $WaveDataFolder
1983                ControlInfo/W=RescaleAxisPanel yModel
1984                ystr = S_Value
1985                ControlInfo/W=RescaleAxisPanel xModel
1986                xstr = S_Value
1987                        if(cmpstr("I",ystr)==0 && cmpstr("q",xstr)==0)
1988                                if(stringmatch(WaveToRescale, "*_i_RA"))
1989                                        oldywave = WaveToRescale
1990                                        ywave = RemoveEnding(WaveToRescale,"_RA")
1991                                        xwave = RemoveEnding(WaveToRescale, "_i_RA")+"_q"
1992                                        replacewave/Y/W=$topGraph trace=$oldywave, $ywave
1993                                        replacewave/X/W=$topGraph trace=$ywave, $xwave
1994                                        swave = RemoveEnding(WaveToRescale, "_i_RA")+"_s"
1995                                        if(exists(swave)==1)
1996                                                ErrorBars/T=0/W=$topGraph $ywave, Y wave=($swave,$swave)       
1997                                        endif
1998                                elseif (stringmatch(WaveToRescale,  "smeared*"))
1999                                        if(stringmatch(WaveToRescale,"*_RA") && stringmatch(WaveToRescale,"!*_qvals*") )
2000                                                oldywave = WaveToRescale
2001                                                ywave = RemoveEnding(WaveToRescale,"_RA")
2002                                                xwave = "smeared_qvals"
2003                                                replacewave/Y/W=$topGraph trace=$oldywave, $ywave
2004                                                replacewave/X/W=$topGraph trace=$ywave, $xwave
2005                                        endif
2006                                elseif(stringmatch(WaveToRescale,"ywave*") && stringmatch(WaveToRescale,"*_RA"))
2007                                        oldywave = WaveToRescale
2008                                        ywave = RemoveEnding(WaveToRescale,"_RA")
2009                                        xwave = ReplaceString("ywave",ywave,"xwave")
2010                                        replacewave/Y/W=$topGraph trace=$oldywave, $ywave
2011                                        replacewave/X/W=$topGraph trace=$ywave, $xwave                                 
2012                                elseif(stringmatch(WaveToRescale, "*FitYw*") && stringmatch(WaveToRescale, "*_RA"))
2013                                        oldywave = WaveToRescale
2014                                        ywave = RemoveEnding(WaveToRescale,"_RA")
2015                                        for (k=1; k < numpnts(WaveString); k+=1)
2016                                                if (stringmatch(Wavestring[k], "*_q"))
2017                                                        xwave = Wavestring[k]
2018                                                endif
2019                                        endfor
2020                                        replacewave/Y/W=$topGraph trace=$oldywave, $ywave
2021                                        replacewave/X/W=$topGraph trace=$ywave, $xwave 
2022                                endif                   
2023                        elseif(stringmatch(WaveToRescale, "*_RA"))
2024                        elseif (stringmatch(WaveToRescale, "*_i"))
2025                                DoWindow/F topGraph
2026                                oldywave = WaveToRescale
2027                                xwave = RemoveEnding(WaveToRescale, "_i")+"_q_RA"
2028                                ywave = WaveToRescale + "_RA"
2029                                replacewave/Y/W=$topGraph trace=$oldywave, $ywave
2030                                replacewave/X/W=$topGraph trace=$ywave, $xwave
2031                                ModifyGraph log=0
2032                                swave = RemoveEnding(WaveToRescale, "_i")+"_s_RA"
2033                                if(exists(swave)==1)
2034                                        ErrorBars/T=0/W=$topGraph $ywave, Y wave=($swave,$swave)       
2035                                endif
2036                                DoUpdate       
2037                        elseif(stringmatch(WaveToRescale, "smeared*") && stringmatch(WaveToRescale, "!*_qvals"))
2038                                oldywave = WaveToRescale
2039                                ywave = WaveToRescale + "_RA"
2040                                replacewave/Y/W=$topGraph trace=$oldywave, $ywave
2041                                xwave = "smeared_qvals_RA"
2042                                replacewave/X/W=$topGraph trace=$ywave, $xwave 
2043                        elseif(stringmatch(WaveToRescale,"ywave*"))
2044                                oldywave = WaveToRescale
2045                                ywave = WaveToRescale + "_RA"
2046                                xwave = ReplaceString("ywave",ywave,"xwave")
2047                                replacewave/Y/W=$topGraph trace=$oldywave, $ywave
2048                                replacewave/X/W=$topGraph trace=$ywave, $xwave                                 
2049                        elseif(stringmatch(WaveToRescale, "*FitYw*"))
2050                                oldywave = WaveToRescale
2051                                ywave = WaveToRescale+"_RA"
2052                                for (k=1; k < numpnts(WaveString); k+=1)
2053                                        if (stringmatch(Wavestring[k], "*_q"))
2054                                                xwave = Wavestring[k]+"_RA"
2055                                        endif
2056                                endfor
2057                                replacewave/Y/W=$topGraph trace=$oldywave, $ywave
2058                                replacewave/X/W=$topGraph trace=$ywave, $xwave 
2059                        endif
2060                        SetDataFolder root:Packages:NIST:RescaleAxis
2061                        DoUpdate
2062                endfor
2063        endfor
2064        KillWaves/A/Z
2065               
2066        string ylabel, xlabel
2067        ControlInfo/W=RescaleAxisPanel yModel
2068        ystr = S_Value
2069        ControlInfo/W=RescaleAxisPanel xModel
2070        xstr = S_Value
2071       
2072        if(cmpstr("I",ystr)==0 && cmpstr("q",xstr)==0)
2073                modifygraph log=1
2074        else
2075                modifygraph log=0
2076        endif
2077       
2078        Variable pow_a,pow_b,pow_c
2079        ControlInfo/W=RescaleAxisPanel expa
2080        pow_a = V_value
2081        ControlInfo/W=RescaleAxisPanel expb
2082        pow_b = V_value
2083        ControlInfo/W=RescaleAxisPanel expc
2084        pow_c = V_value
2085       
2086        If (cmpstr("I",ystr) == 0)
2087                ylabel = "I(q)"
2088        elseif (cmpstr("ln(I)",ystr) == 0)
2089                ylabel = "ln(I)"
2090        elseif (cmpstr("log(I)",ystr) == 0)
2091                ylabel = "log(I)"
2092        elseif (cmpstr("1/I",ystr) == 0)
2093                ylabel = "1/I"
2094        elseif (cmpstr("I^a",ystr) == 0)
2095                ylabel = "I\S"+num2str(pow_a)+"\M"
2096        elseif (cmpstr("Iq^a",ystr) == 0)
2097                ylabel = "Iq\S"+num2str(pow_a)+"\M"
2098        elseif (cmpstr("I^a q^b",ystr) == 0)
2099                ylabel = "I\S"+num2str(pow_a)+"\Mq\S"+num2str(pow_b)+"\M"
2100        elseif (cmpstr("1/sqrt(I)",ystr) == 0)
2101                ylabel = "1/sqrt(I)"
2102        elseif (cmpstr("ln(Iq)",ystr) == 0)
2103                ylabel = "ln(Iq)"
2104        elseif (cmpstr("ln(Iq^2)",ystr) == 0)
2105                ylabel = "ln(Iq\S2\M)"
2106        endif
2107
2108        If (cmpstr("q",xstr) == 0)
2109                xlabel = "q (A\S-1\M)"
2110        elseif (cmpstr("q^2",xstr) == 0)
2111                xlabel = "q\S2\M"
2112        elseif (cmpstr("log(q)",xstr) == 0)
2113                xlabel = "log(q)"
2114        elseif (cmpstr("q^c",xstr) == 0)
2115                xlabel = "q\S"+num2str(pow_c)+"\M"
2116        endif
2117       
2118        SetAxis/A
2119        Label left ylabel
2120        Label bottom xlabel
2121       
2122        SetDataFolder root:
2123End
2124
2125Function YRescale(ywave, xwave)
2126        String ywave,xwave
2127 
2128        Wave yw = $ywave
2129        Wave xw = $xwave
2130       
2131        //Scaling exponents and background value
2132        Variable pow_a,pow_b,pow_c
2133        ControlInfo/W=RescaleAxisPanel expa
2134        pow_a = V_value
2135        ControlInfo/W=RescaleAxisPanel expb
2136        pow_b = V_value
2137        ControlInfo/W=RescaleAxisPanel expc
2138        pow_c = V_value
2139       
2140        //check for physical limits on exponent values
2141        // if bad values found, alert, and reset to good values so the rescaling can continue
2142        NVAR gA = root:Packages:NIST:RescaleAxis:gRAExpA
2143        NVAR gB = root:Packages:NIST:RescaleAxis:gRAExpB
2144        NVAR gC = root:Packages:NIST:RescaleAxis:gRAExpC
2145        if((pow_a < -2) || (pow_a > 10))
2146                DoAlert 0,"Exponent a must be in the range (-2,10) - the exponent a has been reset to 1"
2147                gA = 1
2148        endif
2149        if((pow_b < 0) || (pow_b > 10))
2150                DoAlert 0,"Exponent b must be in the range (0,10) - the exponent b has been reset to 1"
2151                gB = 1
2152        endif
2153        //if q^c is the x-scaling, c must be be within limits and also non-zero
2154        ControlInfo/W=RescaleAxisPanel xModel
2155        If (cmpstr("q^c",S_Value) == 0)
2156                if(pow_c == 0)
2157                        DoAlert 0,"Exponent c must be non-zero, c has been reset to 1"
2158                        gC = 1
2159                endif
2160                if((pow_c < -10) || (pow_c > 10))
2161                        DoAlert 0,"Exponent c must be in the range (-10,10), c has been reset to 1"
2162                        gC = 1
2163                endif
2164        endif
2165       
2166        //variables set for each model to control look of graph
2167        String ystr, yAxis
2168        //check for proper y-scaling selection, make the necessary waves
2169//      Wave yAxisWave
2170
2171        ControlInfo/W=RescaleAxisPanel yModel
2172        ystr = S_Value
2173       
2174        do
2175                If (cmpstr("I",S_Value) == 0)
2176                        yAxis = ywave+"_RA"
2177                        if (exists(yAxis)== 0)
2178                                Duplicate yw $yAxis
2179                        endif
2180                        SetScale d 0,0,"1/cm",$yAxis
2181                        wave yAxisWave = $yAxis
2182                        yAxisWave = yw
2183                        break   
2184                endif
2185                If (cmpstr("ln(I)",S_Value) == 0)
2186                        yAxis = ywave+"_RA"
2187                        if (exists(yAxis)== 0)
2188                                Duplicate yw $yAxis
2189                        endif
2190                        SetScale d 0,0,"",$yAxis
2191                        wave yAxisWave = $yAxis
2192                        yAxisWave = ln(yw)
2193                        break   
2194                endif
2195                If (cmpstr("log(I)",S_Value) == 0)
2196                        yAxis = ywave+"_RA"
2197                        if (exists(yAxis)== 0)
2198                                Duplicate yw $yAxis
2199                        endif
2200                        SetScale d 0,0,"",$yAxis
2201                        wave yAxisWave = $yAxis
2202                        yAxisWave = log(yw)
2203                        break   
2204                endif
2205                If (cmpstr("1/I",S_Value) == 0)
2206                        yAxis = ywave+"_RA"
2207                        if (exists(yAxis)== 0)
2208                                Duplicate yw $yAxis
2209                        endif
2210                        SetScale d 0,0,"",$yAxis
2211                        wave yAxisWave = $yAxis
2212                        yAxisWave = 1/(yw)
2213                        break
2214                endif
2215                If (cmpstr("I^a",S_Value) == 0)
2216                        yAxis = ywave+"_RA"
2217                        if (exists(yAxis)== 0)
2218                                Duplicate yw $yAxis
2219                        endif
2220                        SetScale d 0,0,"",$yAxis
2221                        wave yAxisWave = $yAxis
2222                        yAxisWave = yw^pow_a
2223                        break
2224                endif
2225                If (cmpstr("Iq^a",S_Value) == 0)
2226                        yAxis = ywave+"_RA"
2227                        if (exists(yAxis)== 0)
2228                                Duplicate yw $yAxis
2229                        endif
2230                        SetScale d 0,0,"",$yAxis
2231                        wave yAxisWave = $yAxis
2232                        yAxisWave = yw*xw^pow_a
2233                        break
2234                endif
2235                If (cmpstr("I^a q^b",S_Value) == 0)
2236                        yAxis = ywave+"_RA"
2237                        if (exists(yAxis)== 0)
2238                                Duplicate yw $yAxis
2239                        endif
2240                        SetScale d 0,0,"",$yAxis
2241                        wave yAxisWave = $yAxis
2242                        yAxisWave = yw^pow_a*xw^pow_b
2243                        break
2244                endif
2245                If (cmpstr("1/sqrt(I)",S_Value) == 0)
2246                        yAxis = ywave+"_RA"
2247                        if (exists(yAxis)== 0)
2248                                Duplicate yw $yAxis
2249                        endif
2250                        SetScale d 0,0,"",$yAxis
2251                        wave yAxisWave = $yAxis
2252                        yAxisWave = 1/sqrt(yw)
2253                        break
2254                endif
2255                If (cmpstr("ln(Iq)",S_Value) == 0)
2256                        yAxis = ywave+"_RA"
2257                        if (exists(yAxis)== 0)
2258                                Duplicate yw $yAxis
2259                        endif
2260                        SetScale d 0,0,"",$yAxis
2261                        wave yAxisWave = $yAxis
2262                        yAxisWave = ln(xw*yw)
2263                        break
2264                endif
2265                If (cmpstr("ln(Iq^2)",S_Value) == 0)
2266                        yAxis = ywave+"_RA"
2267                        if (exists(yAxis)== 0)
2268                                Duplicate yw $yAxis
2269                        endif
2270                        SetScale d 0,0,"",$yAxis
2271                        wave yAxisWave = $yAxis
2272                        yAxisWave = ln(xw*xw*yw)
2273                        break
2274                endif
2275                //more ifs for each case
2276               
2277                // if selection not found, abort
2278                DoAlert 0,"Y-axis scaling incorrect. Aborting"
2279                Abort
2280        while(0)
2281End
2282
2283Function XRescale(xwave)       
2284        String xwave
2285 
2286        Wave xw = $xwave
2287                 
2288        //Scaling exponents and background value
2289        Variable pow_a,pow_b,pow_c
2290        ControlInfo/W=RescaleAxisPanel expa
2291        pow_a = V_value
2292        ControlInfo/W=RescaleAxisPanel expb
2293        pow_b = V_value
2294        ControlInfo/W=RescaleAxisPanel expc
2295        pow_c = V_value
2296       
2297//check for physical limits on exponent values
2298// if bad values found, alert, and reset to good values so the rescaling can continue
2299        NVAR gA = root:Packages:NIST:RescaleAxis:gRAExpA
2300        NVAR gB = root:Packages:NIST:RescaleAxis:gRAExpB
2301        NVAR gC = root:Packages:NIST:RescaleAxis:gRAExpC
2302        if((pow_a < -2) || (pow_a > 10))
2303                DoAlert 0,"Exponent a must be in the range (-2,10) - the exponent a has been reset to 1"
2304                gA = 1
2305        endif
2306        if((pow_b < 0) || (pow_b > 10))
2307                DoAlert 0,"Exponent b must be in the range (0,10) - the exponent b has been reset to 1"
2308                gB = 1
2309        endif
2310        //if q^c is the x-scaling, c must be be within limits and also non-zero
2311        ControlInfo/W=RescaleAxisPanel xModel
2312        If (cmpstr("q^c",S_Value) == 0)
2313                if(pow_c == 0)
2314                        DoAlert 0,"Exponent c must be non-zero, c has been reset to 1"
2315                        gC = 1
2316                endif
2317                if((pow_c < -10) || (pow_c > 10))
2318                        DoAlert 0,"Exponent c must be in the range (-10,10), c has been reset to 1"
2319                        gC = 1
2320                endif
2321        endif
2322       
2323        //variables set for each model to control look of graph
2324        String xstr, xAxis
2325        //check for proper y-scaling selection, make the necessary waves
2326//      Wave xAxisWave
2327
2328        ControlInfo/W=RescaleAxisPanel xModel
2329        xstr = S_Value
2330        do
2331                // make the new yaxis wave
2332                If (cmpstr("q",S_Value) == 0)   
2333                        xAxis = xwave+"_RA"
2334                        if (exists(xAxis)== 0)
2335                                Duplicate xw $xAxis
2336                        endif
2337                        SetScale d 0,0,"A^-1",$xAxis
2338                        wave xAxisWave = $xAxis
2339                        xAxisWave = xw
2340                        break   
2341                endif
2342                If (cmpstr("q^2",S_Value) == 0)
2343                        xAxis = xwave+"_RA"
2344                        if (exists(xAxis)== 0)
2345                                Duplicate xw $xAxis
2346                        endif
2347                        SetScale d 0,0,"A^-2",$xAxis
2348                        wave xAxisWave = $xAxis
2349                        xAxisWave = xw*xw
2350                        break   
2351                endif
2352                If (cmpstr("log(q)",S_Value) == 0)     
2353                        xAxis = xwave+"_RA"
2354                        if (exists(xAxis)== 0)
2355                                Duplicate xw $xAxis
2356                        endif
2357                        SetScale d 0,0,"",$xAxis
2358                        wave xAxisWave = $xAxis
2359                        xAxisWave = log(xw)
2360                        break   
2361                endif
2362                If (cmpstr("q^c",S_Value) == 0)
2363                        xAxis = xwave+"_RA"
2364                        if (exists(xAxis)== 0)
2365                                Duplicate xw $xAxis
2366                        endif
2367                        SetScale d 0,0,"", $xAxis
2368                        wave xAxisWave = $xAxis
2369                        xAxisWave = xw^pow_c
2370                        break
2371                endif
2372       
2373                //more ifs for each case
2374                // if selection not found, abort
2375                DoAlert 0,"X-axis scaling incorrect. Aborting"
2376                Abort
2377        while(0)        //end of "case" statement for x-axis scaling
2378End
2379
2380Function ERescale(swave, ywave, xwave) 
2381        String swave, ywave, xwave
2382 
2383        Wave ew = $swave
2384        Wave yw = $ywave
2385        Wave xw = $xwave
2386                 
2387        //Scaling exponents and background value
2388        Variable pow_a,pow_b,pow_c
2389        ControlInfo/W=RescaleAxisPanel expa
2390        pow_a = V_value
2391        ControlInfo/W=RescaleAxisPanel expb
2392        pow_b = V_value
2393        ControlInfo/W=RescaleAxisPanel expc
2394        pow_c = V_value
2395       
2396//check for physical limits on exponent values
2397// if bad values found, alert, and reset to good values so the rescaling can continue
2398        NVAR gA = root:Packages:NIST:RescaleAxis:gRAExpA
2399        NVAR gB = root:Packages:NIST:RescaleAxis:gRAExpB
2400        NVAR gC = root:Packages:NIST:RescaleAxis:gRAExpC
2401        if((pow_a < -2) || (pow_a > 10))
2402                DoAlert 0,"Exponent a must be in the range (-2,10) - the exponent a has been reset to 1"
2403                gA = 1
2404        endif
2405        if((pow_b < 0) || (pow_b > 10))
2406                DoAlert 0,"Exponent b must be in the range (0,10) - the exponent b has been reset to 1"
2407                gB = 1
2408        endif
2409        //if q^c is the x-scaling, c must be be within limits and also non-zero
2410        ControlInfo/W=RescaleAxisPanel xModel
2411        If (cmpstr("q^c",S_Value) == 0)
2412                if(pow_c == 0)
2413                        DoAlert 0,"Exponent c must be non-zero, c has been reset to 1"
2414                        gC = 1
2415                endif
2416                if((pow_c < -10) || (pow_c > 10))
2417                        DoAlert 0,"Exponent c must be in the range (-10,10), c has been reset to 1"
2418                        gC = 1
2419                endif
2420        endif
2421       
2422        //variables set for each model to control look of graph
2423        String ystr, eWave
2424        //check for proper y-scaling selection, make the necessary waves
2425//      Wave yErrWave
2426
2427        ControlInfo/W=RescaleAxisPanel yModel
2428        ystr = S_Value
2429        do
2430               
2431                If (cmpstr("I",S_Value) == 0)
2432                        eWave = swave+"_RA"
2433                        if (exists(eWave) == 0)
2434                                Duplicate ew $eWave
2435                        endif
2436                        wave yErrWave = $eWave
2437                        yErrWave = ew
2438                        break   
2439                endif
2440                If (cmpstr("ln(I)",S_Value) == 0)
2441                        eWave = swave+"_RA"
2442                        if (exists(eWave) == 0)
2443                                Duplicate ew $eWave
2444                        endif
2445                        wave yErrWave = $eWave
2446                        yErrWave = ew/yw
2447                        break   
2448                endif
2449                If (cmpstr("log(I)",S_Value) == 0)
2450                        eWave = swave+"_RA"
2451                        if (exists(eWave) == 0)
2452                                Duplicate ew $eWave
2453                        endif
2454                        wave yErrWave = $eWave
2455                        yErrWave = ew/(2.30*yw)
2456                        break   
2457                endif
2458                If (cmpstr("1/I",S_Value) == 0)
2459                        eWave = swave+"_RA"
2460                        if (exists(eWave) == 0)
2461                                Duplicate ew $eWave
2462                        endif
2463                        wave yErrWave = $eWave
2464                        yErrWave = ew/(yw^2)
2465                        break
2466                endif
2467                If (cmpstr("I^a",S_Value) == 0)
2468                        eWave = swave+"_RA"
2469                        if (exists(eWave) == 0)
2470                                Duplicate ew $eWave
2471                        endif
2472                        wave yErrWave = $eWave
2473                        yErrWave = ew*abs(pow_a*(yw^(pow_a-1)))
2474                        break
2475                endif
2476                If (cmpstr("Iq^a",S_Value) == 0)
2477                        eWave = swave+"_RA"
2478                        if (exists(eWave) == 0)
2479                                Duplicate ew $eWave
2480                        endif
2481                        wave yErrWave = $eWave
2482                        yErrWave = ew*xw^pow_a
2483                        break
2484                endif
2485                If (cmpstr("I^a q^b",S_Value) == 0)
2486                        eWave = swave+"_RA"
2487                        if (exists(eWave) == 0)
2488                                Duplicate ew $eWave
2489                        endif
2490                        wave yErrWave = $eWave
2491                        yErrWave = ew*abs(pow_a*(yw^(pow_a-1)))*xw^pow_b
2492                        break
2493                endif
2494                If (cmpstr("1/sqrt(I)",S_Value) == 0)
2495                        eWave = swave+"_RA"
2496                        if (exists(eWave) == 0)
2497                                Duplicate ew $eWave
2498                        endif
2499                        wave yErrWave = $eWave
2500                        yErrWave = 0.5*ew*yw^(-1.5)
2501                        break
2502                endif
2503                If (cmpstr("ln(Iq)",S_Value) == 0)
2504                        eWave = swave+"_RA"
2505                        if (exists(eWave) == 0)
2506                                Duplicate ew $eWave
2507                        endif
2508                        wave yErrWave = $eWave
2509                        yErrWave =ew/yw
2510                        break
2511                endif
2512                If (cmpstr("ln(Iq^2)",S_Value) == 0)
2513                        eWave = swave+"_RA"
2514                        if (exists(eWave) == 0)
2515                                Duplicate ew $eWave
2516                        endif
2517                        wave yErrWave = $eWave
2518                        yErrWave = ew/yw
2519                        break
2520                endif
2521                //more ifs for each case
2522               
2523                // if selection not found, abort
2524                DoAlert 0,"Y-axis scaling incorrect. Aborting"
2525                Abort
2526        while(0)        //end of "case" statement for y-axis scaling
2527
2528End
2529
2530///////////////////////////
2531
Note: See TracBrowser for help on using the repository browser.