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

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

Added an ".ifn" extension back to the Report notebooks so that they are properly recognized on Windows.

No real changes to the help files (just compiled) other than SANS_Models where there was an extraneous Topic definition. We'll see if this fixes the help link errors.

File size: 72.8 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,26]         //if shorter than 31, this will NOT pad to 31 characters
1194                nameStr += ".ifn"                       //extension is needed, otherwise the files are not recognized on Windows
1195               
1196                Print "file saved as ",nameStr
1197                SaveNotebook /O/P=home/S=2 $nb as nameStr
1198                //save the graph separately as a PNG file, 2x screen
1199                pictStr += nameStr
1200                pictStr = pictStr[0,24]+".png"          //need a shorter name - only 29 characters allowed - why?
1201//              DoWindow/F $topGraph
1202                // E=-5 is png @screen resolution
1203                // E=2 is PICT @2x screen resolution
1204///             SavePICT /E=-5/O/P=home /I/W=(0,0,3,3) as pictStr
1205                if(WaveExists(dataXw))
1206                        SavePICT /E=-5/O/P=home/WIN=$topGraph /W=(0,0,800,600) as pictStr
1207                else
1208                        Execute "ExportGizmo /P=home as \""+pictStr+"\""                //this won't be of very high quality
1209                        //SavePICT /E=-5/O/P=home/WIN=$topGraph /W=(0,0,400,300) as pictStr
1210                endif
1211        Endif
1212       
1213        // ???maybe print the notebook too?
1214End
1215
1216Function/S W_ErrorMessage(code)
1217        Variable code
1218       
1219        switch (code)
1220                case 0:
1221                        return "No Error"
1222                        break
1223                case 3: //2^0 + 2^1
1224                        return "Singular Matrix"
1225                        break
1226                case 5:         //(2^0 + 2^2)
1227                        return "Out of Memory"
1228                        break
1229                case 9:         //(2^0 + 2^3)
1230                        return "Func= NaN or Inf"
1231                        break
1232                default:
1233                        return "Unknown error code "+num2str(code)
1234        endswitch
1235end
1236
1237Function/S W_QuitMessage(code)
1238        Variable code
1239       
1240        switch (code)
1241                case 0:
1242                        return "No Error"
1243                        break
1244                case 1:
1245                        return "Max iterations - re-run fit"
1246                        break
1247                case 2:
1248                        return "User terminated fit"
1249                        break
1250                case 3:
1251                        return "No decrease in chi-squared"
1252                        break
1253                default:
1254                        return "Unknown Quit code "+num2str(code)
1255        endswitch
1256end
1257
1258Function UseInfoTextBoxCheckProc(cba) : CheckBoxControl
1259        STRUCT WMCheckboxAction &cba
1260
1261        switch( cba.eventCode )
1262                case 2: // mouse up
1263                        Variable checked = cba.checked
1264                        if(checked)
1265                                //print "checked, use textBox in the next fit"
1266                        else
1267                                //print "unchecked, ask to remove TextBox from the graph"
1268                                ControlInfo/W=WrapperPanel popup_0
1269                                RemoveTextBox(S_value)
1270                        endif
1271                        break
1272        endswitch
1273
1274        return 0
1275End
1276
1277//does not report an error if the text box is not there
1278// -- so I'll just be lazy and not check to see if it's there
1279//
1280Function RemoveTextBox(folderStr)
1281        String folderStr
1282       
1283        DoAlert 1,"Remove the TextBox from the graph?"
1284        if(V_flag == 1)
1285                String str = "CF_"+folderStr+"_i"
1286                TextBox/K/N=$str
1287        endif
1288        return(0)
1289End
1290
1291Function UseResidualsCheckProc(cba) : CheckBoxControl
1292        STRUCT WMCheckboxAction &cba
1293
1294        switch( cba.eventCode )
1295                case 2: // mouse up
1296                        Variable checked = cba.checked
1297                        if(checked)
1298                                //print "checked, use them in the next fit"
1299                        else
1300                                //print "unchecked, ask to remove residuals from the graph"
1301                                ControlInfo/W=WrapperPanel popup_0
1302                                RemoveResiduals(S_value)
1303                        endif
1304                        break
1305        endswitch
1306
1307        return 0
1308End
1309
1310// the default name from the /R flag is "Res_" + yWaveName
1311//
1312// better to find the wave that starts with "Res_" and remove that one in case the
1313// wave names get too long
1314//
1315// the difficulty now is that the residual wave ends up in root: and not with the data....
1316// -- not really a problem, but adds to clutter
1317Function RemoveResiduals(folderStr)
1318        String folderStr
1319       
1320        String list="",topWin=""
1321        Variable num,ii
1322        String str
1323
1324        DoAlert 1,"Remove the residuals from the graph?"
1325        if(V_flag == 1)
1326//              String topGraph= WinName(0,1)   //this is the topmost graph
1327                list=TraceNameList("", ";", 1 )         //"" as first parameter == look on the target graph
1328                num=ItemsInList(list)
1329               
1330                for(ii=0;ii<num;ii+=1)
1331                        str = StringFromList(ii, list ,";")
1332                        if(strsearch(str, "Res_", 0) != -1)
1333                                RemoveFromGraph $str
1334                        endif
1335                endfor
1336       
1337                SetDataFolder root:
1338        endif
1339       
1340        return(0)
1341End
1342
1343Function Toggle2DControlsCheckProc(cba) : CheckBoxControl
1344        STRUCT WMCheckboxAction &cba
1345
1346        switch( cba.eventCode )
1347                case 2: // mouse up
1348                        Variable checked = cba.checked
1349                        if(checked)
1350                                //print "change the buttons to 2D"
1351                                Button button_0,proc=Do2DFitButtonProc,title="Do 2D Fit"
1352                                Button button_1,size={120,20},proc=Plot2DFunctionButtonProc,title="Plot 2D Function"
1353                                Button button_2,size={100,20},proc=Append2DModelButtonProc,title="Append 2D"
1354                                Button button_3,size={100,20},proc=Load2DDataButtonProc,title="Load 2D Data"
1355                               
1356                                Button button_2D_0,pos={550,60},size={70,20},proc=LogToggle2DButtonProc,title="Log/Lin"
1357                                Button button_2D_1,pos={520,37},size={100,20},proc=Plot2DButtonProc,title="Plot 2D Data"
1358                               
1359                                Button button_2D_0,disable=0            //visible again, and enabled
1360                                Button button_2D_1,disable=0
1361                               
1362                                CheckBox check_6,disable=1                      //info box and residual check, remove these from view
1363                                CheckBox check_7,disable=1
1364                                CheckBox check_8,disable=1
1365                        else
1366                                //print "unchecked, change them back to 1D"
1367                                Button button_0,pos={520,93},size={100,20},proc=DoTheFitButton,title="Do 1D Fit"
1368                                Button button_1,pos={280,57},size={120,20},proc=PlotModelFunction,title="Plot 1D Function"
1369                                Button button_2,pos={300,93},size={100,20},proc=AppendModelToTarget,title="Append 1D"
1370                                Button button_3,pos={300,20},size={100,20},proc=W_LoadDataButtonProc,title="Load 1D Data"
1371                               
1372                                Button button_2D_0,disable=3    //hide the extra 2D buttons, and disable
1373                                Button button_2D_1,disable=3
1374                               
1375                                CheckBox check_6,disable=0                      //info box and residual check, bring them back
1376                                CheckBox check_7,disable=0
1377                                CheckBox check_8,disable=0
1378                        endif
1379                        break
1380        endswitch
1381
1382        return 0
1383End
1384
1385// function to either add or remove the cursors from the topmost graph, as needed
1386
1387Function UseCursorsWrapperProc(cba) : CheckBoxControl
1388        STRUCT WMCheckboxAction &cba
1389
1390
1391        switch( cba.eventCode )
1392                case 2: // mouse up
1393               
1394                        // check to make sure there really is a "topmost" graph         
1395                        String topGraph= WinName(0,1)   //this is the topmost graph
1396                        if(cmpstr(topGraph,"")==0)      //no graphs, uncheck and exit
1397                                CheckBox check_0,value=0
1398                                return(0)
1399                        endif
1400                       
1401                        //if in 2D mode, just exit
1402                        ControlInfo/W=WrapperPanel check_3
1403                        if(V_Value == 1)
1404                                return (0)
1405                        endif
1406                               
1407                        String ciStr = CsrInfo(A , topGraph)
1408                       
1409                        ControlInfo/W=wrapperpanel popup_0
1410                        String folderStr=S_Value
1411                        String traceList = TraceNameList(topGraph, ";", 1 )             
1412               
1413                        Variable checked = cba.checked
1414                       
1415                        if(checked)
1416                                //print "add the cursors to the topmost graph, if the data set is there, or move them"
1417                                if(strlen(ciStr)==0 && strsearch(traceList, folderStr, 0) != -1 )               //no cursors && data is there
1418                                        ShowInfo
1419                                        Wave yw=$("root:"+folderStr+":"+folderStr+"_i")
1420                                        Cursor/P/W=$topGraph A, $(folderStr+"_i"),0
1421                                        Cursor/P/W=$topGraph/A=0 B, $(folderStr+"_i"),numpnts(yw)-1                     //deactivate the one at the high Q end
1422                                        DoUpdate
1423                                elseif (strlen(ciStr)!=0 && strsearch(traceList, folderStr, 0) != -1 ) //cursors present, but on wrong data
1424                                        Wave yw=$("root:"+folderStr+":"+folderStr+"_i")
1425                                        Cursor/P/W=$topGraph A, $(folderStr+"_i"),0                                                             //move the cursors
1426                                        Cursor/P/W=$topGraph/A=0 B, $(folderStr+"_i"),numpnts(yw)-1
1427                                        DoUpdate
1428                                endif
1429                               
1430                                AreCursorsCorrect(folderStr)
1431                        else
1432                                //print "unchecked, remove the cursors"
1433                                // go back to the full matrix for the resolution calculation (not if SANS data...)
1434                                if(waveExists($("root:"+folderStr+":weights_save")))
1435                                        Duplicate/O $("root:"+folderStr+":weights_save"), $("root:"+folderStr+":"+folderStr+"_res"),$("root:"+folderStr+":"+folderStr+"_rest")
1436                                endif
1437
1438                                HideInfo/W=$topGraph
1439                                Cursor/K A
1440                                Cursor/K B
1441                        endif
1442                        break
1443        endswitch
1444
1445        return 0
1446End
1447
1448// returns 1 if the specified data is on the top graph && has cursors on it
1449// returns 0 and unchecks the box if anything is wrong
1450//
1451// only call this function if the cursor box is checked, to uncheck it as needed
1452// if the box is unchecked, leave it be.
1453//
1454Function AreCursorsCorrect(folderStr)
1455        String folderStr
1456       
1457        String topGraph= WinName(0,1)   //this is the topmost graph
1458        if(cmpstr(topGraph,"")==0)      //no graphs, uncheck and exit
1459                CheckBox check_0,win=wrapperpanel,value=0
1460                return(0)
1461        endif
1462               
1463        String traceAisOn = CsrWave(A , "", 0)
1464        if(     strsearch(traceAisOn, folderStr, 0) == -1)              //data and cursors don't match
1465                CheckBox check_0,win=wrapperpanel,value=0
1466                HideInfo
1467                Cursor/K A
1468                Cursor/K B
1469                return(0)
1470        endif
1471       
1472        return(1)
1473End
1474
1475
1476
1477//////////////////////////////
1478//
1479// displays the covariance matrix for the current data set in the popup
1480// AND whatever was the last fit for that data set. it may not necessarily
1481// be the displayed function...
1482Function DisplayCovarianceMatrix()
1483
1484       
1485
1486        ControlInfo/W=wrapperpanel popup_0
1487        String folderStr=S_Value
1488
1489        ControlInfo/W=WrapperPanel popup_1
1490        String funcStr=S_Value
1491                       
1492        if(Stringmatch(funcStr,"Smear*"))               //simple test for smeared function
1493                if(DataFolderExists("root:"+folderStr))
1494                        SetDataFolder $("root:"+folderStr)
1495                else
1496                        SetDataFolder root:
1497                endif
1498        else
1499                SetDataFolder root:
1500        endif
1501       
1502        Wave M_Covar=M_Covar
1503        Duplicate/O M_Covar, CorMat      // You can use any name instead of CorMat
1504        CorMat = M_Covar[p][q]/sqrt(M_Covar[p][p]*M_Covar[q][q])
1505
1506        // clear the table (a subwindow)
1507        DoWindow/F CorMatPanel                          // ?? had to add this in during all of the cursor meddling...
1508        KillWindow CorMatPanel#T0
1509        Edit/W=(20,74,634,335)/HOST=CorMatPanel
1510        RenameWindow #,T0
1511        // get them onto the table
1512        // how do I get the parameter name?
1513        String param = getFunctionParams(funcStr)
1514        AppendtoTable/W=CorMatPanel#T0 $param
1515        AppendToTable/W=CorMatPanel#T0 CorMat
1516        ModifyTable/W=CorMatPanel#T0 width(Point)=0
1517
1518        GroupBox grpBox_1 title="Data set: "+folderStr
1519        GroupBox grpBox_2 title="Function: "+funcStr
1520
1521
1522        SetDataFolder root:
1523       
1524        return(0)
1525End
1526
1527
1528Window CorMatPanel()
1529        PauseUpdate; Silent 1           // building window...
1530        NewPanel /W=(459,44,1113,399)/N=CorMatPanel/K=1 as "Correlation Matrix"
1531        ModifyPanel fixedSize=1
1532       
1533        GroupBox grpBox_1 title="box 1",pos={10,20},size={0,0},frame=1,fSize=10,fstyle=1,fColor=(39321,1,1)
1534        GroupBox grpBox_2 title="box 2",pos={10,40},size={0,0},frame=1,fSize=10,fstyle=1,fColor=(39321,1,1)
1535
1536        Button button_1,pos={520,30},size={100,20},proc=CorMatHelpButtonProc,title="Help"
1537
1538        Edit/W=(20,74,634,335)/HOST=# 
1539        ModifyTable width(Point)=0
1540        RenameWindow #,T0
1541        SetActiveSubwindow ##
1542EndMacro
1543
1544
1545Proc DisplayCovariance()
1546        DoWindow/F CorMatPanel
1547        if(V_Flag==0)
1548                CorMatPanel()
1549        endif
1550       
1551        DisplayCovarianceMatrix()
1552
1553End
1554
1555//open the Help file for the Fit Manager
1556Function CorMatHelpButtonProc(ba) : ButtonControl
1557        STRUCT WMButtonAction &ba
1558
1559        switch( ba.eventCode )
1560                case 2: // mouse up
1561                        // click code here
1562                        DisplayHelpTopic/Z/K=1 "Covariance Matrix"
1563                        if(V_flag !=0)
1564                                DoAlert 0,"Help for the correlation matrix could not be found"
1565                        endif
1566                        break
1567        endswitch
1568
1569        return 0
1570End
1571
1572
1573//////////////////////////////////
1574// this is a snippet from Andy Nelson, posted at the Igor Exchange web site.
1575//
1576// search area appears to be a percent (so enter 10 to get +/- 10% variation in the parameter)
1577//
1578// TODO:
1579//              x- rename the function for just me
1580//              x- make the edata a mandatory parameter
1581//              x- remove rhs, lhs? or keep these if cursors were used to properly trim the data set
1582//              x- label the graph
1583//              x- make a panel to control this - to either pick a single parameter, or show all of them
1584//              x- have it re-use the same graph, not draw a (new) duplicate one
1585//              x- update it to use the AAO as the input function (new func template -- see Gauss Utils)
1586//              x- the wrapper must be data folder aware, and data set aware like in the Wrapper panel
1587//              x- need a different wrapper for smeared and unsmeared functions
1588//
1589//
1590
1591
1592
1593Proc MapChiSquared(paramNum,percent)
1594        Variable paramNum=0,percent=10
1595        Prompt paramNum, "Enter parameter number: "
1596        Prompt percent, "Enter percent variation +/- : "
1597
1598        fChiMap(paramNum,percent)
1599End
1600
1601
1602// this does the math for a single value of "whichParam"
1603Function chi2gen(funcStr,folderStr,xw,yw,sw,cw,whichParam,searchArea,lhs,rhs,useResol)
1604        String funcStr,folderStr
1605        Wave xw,yw,sw,cw      //        x data, y data, error wave, and coefficient wave
1606        variable whichParam, searchArea  //which of the parameters to you want to vary, how far from the original value do you want to search (%)
1607        variable lhs, rhs    //specify a region of interest in the data using a left hand side and right hand side.
1608        variable useResol               // =1 if smeared used
1609 
1610        variable originalvalue = cw[whichparam]
1611        variable range = originalValue * searchArea/100
1612        variable ii,err
1613 
1614        duplicate/o yw, :theoretical_data, :chi2_data
1615        Wave theoretical_data, chi2_data
1616 
1617        make/o/n=200/d chi2_map
1618        setscale/I x,  originalvalue - range/2, originalvalue + range/2, chi2_map
1619 
1620        String DF="root:"+folderStr+":"
1621        String suffix=getModelSuffix(funcStr)
1622
1623        // fill a struct instance whether it is needed or not
1624        Struct ResSmearAAOStruct fs
1625        WAVE/Z resW = $(DF+folderStr+"_res")                    //these may not exist, if 3-column data is used
1626        WAVE/Z fs.resW =  resW
1627//              WAVE yw=$(DF+folderStr+"_i")
1628//              WAVE xw=$(DF+folderStr+"_q")
1629//              WAVE sw=$(DF+folderStr+"_s")
1630        Wave fs.coefW = cw
1631        Wave fs.yW = theoretical_data
1632        Wave fs.xW = xw
1633 
1634 
1635 
1636        for(ii=0 ; ii < numpnts(chi2_map) ; ii+=1)
1637                cw[whichparam] = pnt2x(chi2_map, ii)
1638 
1639                if(useResol)
1640                        FUNCREF SANSModelSTRUCT_proto func1=$funcStr
1641                        err = func1(fs)
1642                else
1643                        FUNCREF SANSModelAAO_proto func2=$funcStr
1644                        func2(cw,theoretical_data,xw)
1645                endif
1646               
1647                chi2_data = (yw-theoretical_data)^2
1648 
1649                chi2_data /= sw^2
1650
1651                Wavestats/q/R=[lhs, rhs] chi2_data
1652 
1653                chi2_map[ii] = V_avg * V_npnts
1654        endfor
1655 
1656        cw[whichparam] = originalvalue
1657 
1658        DoWindow/F Chi2
1659        if(V_flag==0)
1660                display/K=1/N=Chi2 chi2_map
1661                Label left "Chi^2"
1662        endif
1663
1664        String parStr=GetWavesDataFolder(cw,1)+ WaveList("*param*"+"_"+suffix, "", "TEXT:1," )          // this is *hopefully* one wave
1665        Wave/T parW = $parStr
1666        Label bottom parW[whichParam]
1667       
1668       
1669        killwaves/z theoretical_data, chi2_data
1670End
1671 
1672
1673// this does the setup
1674Function fChiMap(paramNum,percent)
1675        Variable paramNum,percent
1676
1677        String folderStr,funcStr,coefStr
1678        Variable useCursors,useResol=0,pt1,pt2
1679       
1680        ControlInfo/W=WrapperPanel popup_0
1681        folderStr=S_Value
1682       
1683        ControlInfo/W=WrapperPanel popup_1
1684        funcStr=S_Value
1685       
1686        ControlInfo/W=WrapperPanel popup_2
1687        coefStr=S_Value
1688       
1689        ControlInfo/W=WrapperPanel check_0
1690        useCursors=V_Value
1691       
1692       
1693// first, figure out where we are...
1694        String suffix=getModelSuffix(funcStr)
1695       
1696        SetDataFolder $("root:"+folderStr)
1697        if(!exists(coefStr))
1698                // must be unsmeared model, work in the root folder
1699                SetDataFolder root:                             
1700                if(!exists(coefStr))            //this should be fine if the coef filter is working, but check anyhow
1701                        DoAlert 0,"the coefficient and data sets do not match"
1702                        return 0
1703                endif
1704        endif
1705               
1706        WAVE cw=$(coefStr)
1707
1708
1709// test for smeared function
1710        if(stringmatch(funcStr, "Smear*"))              // if it's a smeared function, need a struct
1711                useResol=1
1712        endif
1713       
1714        // fill a struct instance whether I need one or not
1715        String DF="root:"+folderStr+":"
1716       
1717//      Struct ResSmearAAOStruct fs
1718//      WAVE/Z resW = $(DF+folderStr+"_res")                    //these may not exist, if 3-column data is used
1719//      WAVE/Z fs.resW =  resW
1720        WAVE yw=$(DF+folderStr+"_i")
1721        WAVE xw=$(DF+folderStr+"_q")
1722        WAVE sw=$(DF+folderStr+"_s")
1723//      Wave fs.coefW = cw
1724//      Wave fs.yW = yw
1725//      Wave fs.xW = xw
1726       
1727        if(useCursors)
1728                if(pcsr(A) > pcsr(B))
1729                        pt1 = pcsr(B)
1730                        pt2 = pcsr(A)
1731                else
1732                        pt1 = pcsr(A)
1733                        pt2 = pcsr(B)
1734                endif
1735        else
1736                //if cursors are not being used, find the first and last points of the data set, and pass them
1737                pt1 = 0
1738                pt2 = numpnts(yw)-1
1739        endif
1740       
1741               
1742       
1743        chi2gen(funcStr,folderStr,xw,yw,sw,cw,paramNum,percent,pt1,pt2,useResol)
1744       
1745
1746End
1747
1748////////////////////////////////////
1749// Modification from Matt Wasbrough to allow rescaling of the
1750// axes while plotting and fitting. allows export of the rescaled
1751// data and of the rescaled model
1752// Nov 2012
1753///
1754
1755Function UseRescaleAxisCheckProc(cba) : CheckBoxControl
1756        STRUCT WMCheckboxAction &cba
1757
1758        switch( cba.eventCode )
1759                case 2: // mouse up
1760                        Variable checked = cba.checked
1761                        if(checked)
1762                                Execute "OpenAxisPanel()"
1763                        else
1764                                if(exists("RescaleAxisPanel") !=0)
1765                                        DoWindow/K RescaleAxisPanel
1766                                endif
1767                        endif
1768                        break
1769        endswitch
1770
1771        return 0
1772End
1773
1774Proc OpenAxisPanel()
1775        If(WinType("RescaleAxisPanel") == 0)
1776                //create the necessary data folder
1777                NewDataFolder/O root:Packages
1778                NewDataFolder/O root:Packages:NIST
1779                NewDataFolder/O root:Packages:NIST:RescaleAxis
1780                //initialize the values
1781                Variable/G root:Packages:NIST:RescaleAxis:gRAExpA = 1
1782                Variable/G root:Packages:NIST:RescaleAxis:gRAExpB = 1
1783                Variable/G root:Packages:NIST:RescaleAxis:gRAExpC = 1
1784                RescaleAxisPanel()
1785        else
1786                //window already exists, just bring to front for update
1787                DoWindow/F RescaleAxisPanel
1788        endif
1789End
1790
1791Window RescaleAxisPanel()
1792        PauseUpdate; Silent 1           // building window...
1793        NewPanel /W=(461,46,735,195)/K=1
1794        ModifyPanel cbRGB=(49360,30954,64507), fixedSize=1
1795        SetDrawLayer UserBack
1796        PopupMenu ymodel,pos={20,10},size={76,19},title="y-axis"
1797        PopupMenu ymodel,help={"This popup selects how the y-axis will be linearized based on the chosen data"}
1798        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)\""
1799        Button GoRescale,pos={50,80},size={70,20},proc=RescalePlot,title="Rescale"
1800        Button GoRescale,help={"This button will rescale the axis using the selections in this panel"}
1801        Button DoneButton,pos={170,80},size={70,20},proc=RADoneButton,title="Done"
1802        Button DoneButton,help={"This button will close the panel"}
1803        Button ExportData, pos={100,110}, size={90,20}, proc=ExportData, title="Export Data"
1804        Button ExportData, help={"This button will export data from the top graph"}
1805        SetVariable expa,pos={13,45},size={80,17},title="pow \"a\""
1806        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"}
1807        SetVariable expa,limits={-2,10,0},value= root:Packages:NIST:RescaleAxis:gRAExpA
1808        SetVariable expb,pos={98,45},size={80,17},title="pow \"b\""
1809        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"}
1810        SetVariable expb,limits={0,10,0},value= root:Packages:NIST:RescaleAxis:gRAExpB
1811        PopupMenu xmodel,pos={155,10},size={79,19},title="x-axis"
1812        PopupMenu xmodel,help={"This popup selects how the x-axis will be linearized given the chosen data"}
1813        PopupMenu xmodel,mode=1,value= #"\"q;log(q);q^2;q^c\""
1814        SetVariable expc,pos={182,45},size={80,17},title="pow \"c\""
1815        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"}
1816        SetVariable expc,limits={-10,10,0},value= root:Packages:NIST:RescaleAxis:gRAExpC
1817        Button RAHelp, pos={220,110}, size={20,20}, proc=RAHelpButtonProc, title="?"
1818EndMacro
1819
1820Proc RADoneButton(ctrlName): ButtonControl
1821        String ctrlName
1822        DoWindow/K RescaleAxisPanel
1823        DoWindow/F WrapperPanel
1824        CheckBox check_8 value=0
1825end
1826
1827Function RAHelpButtonProc(ba) : ButtonControl
1828        STRUCT WMButtonAction &ba
1829
1830        switch( ba.eventCode )
1831                case 2: // mouse up
1832                        // click code here
1833                        DisplayHelpTopic/Z/K=1 "Rescaled Axis"
1834                        if(V_flag !=0)
1835                                DoAlert 0,"The Rescaled Axis Help file could not be found"
1836                        endif
1837                        break
1838        endswitch
1839
1840        return 0
1841End
1842
1843Proc ExportData(ctrlName): ButtonControl
1844        string ctrlName
1845        WriteRescaledData()             
1846End
1847       
1848
1849Function RescalePlot (ctrlName): ButtonControl
1850        String ctrlName
1851        SetDataFolder root:
1852        String topGraph= WinName(0,1)   //this is the topmost graph
1853        if(strlen(topGraph)==0)
1854                Abort "There is no graph"
1855        endif
1856               
1857        DoWindow/F $topGraph
1858        GetWindow/Z $topGraph, wavelist
1859        wave/t W_Wavelist
1860        SetDataFolder root:Packages:NIST:RescaleAxis
1861        if (exists("W_WaveList")==1)
1862                KillWaves/Z root:Packages:NIST:RescaleAxis:W_WaveList
1863        endif
1864        MoveWave root:W_WaveList, root:Packages:NIST:RescaleAxis:W_WaveList
1865        SetDataFolder root:Packages:NIST:RescaleAxis
1866        variable i,j,k
1867        string DF,DF1,temp, temp2, t1
1868        for (i=0; i < numpnts(W_WaveList)/3; i+=1)
1869                temp = W_WaveList[i][1]
1870                if (stringmatch(temp, "*_i") || stringmatch(temp, "*_i_RA"))
1871                        temp = W_WaveList[i][0]
1872                        if(stringmatch(temp, "*_i"))
1873                                temp = removeending(temp, "_i")
1874                        elseif(stringmatch(temp, "*_i_RA"))
1875                                temp = removeending(temp, "_i_RA")
1876                        endif
1877                        Make/T/O $temp/Wave=tempWave
1878                        DF = ReplaceString(W_Wavelist[i][0],W_Wavelist[i][1],"")
1879                        if (strlen(DF) ==0)
1880                                DF = ":"
1881                        endif
1882                        DF1 = "root"+DF
1883                        tempWave[0] = DF1
1884                        k = 1
1885                        for(j=0;j<numpnts(W_WaveList)/3; j+=1)
1886                                if (stringmatch(W_WaveList[j][1], "*"+temp+"*"))
1887                                        tempWave[k] = W_WaveList[j][0]
1888                                        k  = k+1
1889                                endif
1890                        endfor
1891                        redimension/N=(k) tempWave
1892                elseif(stringmatch(temp, "*ywave*"))
1893                        temp = W_WaveList[i][0]
1894                        if(stringmatch(temp, "*_RA"))
1895                                temp = removeending(temp, "_RA")
1896                        endif                   
1897                        Make/T/O $temp/Wave=tempWave
1898                        DF = ReplaceString(W_Wavelist[i][0],W_Wavelist[i][1],"")
1899                        if (strlen(DF) ==0)
1900                                DF = ":"
1901                        endif
1902                        DF1 = "root"+DF
1903                        tempWave[0] = DF1
1904                        temp2 = replacestring("ywave", temp, "")
1905                        k = 1
1906                        for(j=0;j<numpnts(W_WaveList)/3; j+=1)
1907                                t1 = W_Wavelist[j][1]
1908                                if (stringmatch(W_WaveList[j][1], "*wave"+temp2+"*"))
1909                                        tempWave[k] = W_WaveList[j][1]
1910                                        k  = k+1
1911                                endif
1912                        endfor
1913                        redimension/N=(k) tempWave
1914                endif
1915        endfor
1916        KillWaves/Z W_Wavelist
1917        string listWave = Wavelist("*", ";", "TEXT:1")
1918        string WaveToRescale, WaveDataFolder,xwave, ywave, swave
1919       
1920        for (i = 0; i < ItemsInList(listWave,";"); i+=1)
1921                temp = StringFromList(i,listWave,";")
1922                Wave/T WaveString = $temp
1923                for (j=1; j < numpnts(WaveString); j+=1)
1924                         WaveToRescale = Wavestring[j]
1925                         if (stringmatch(WaveToRescale, "*_RA"))
1926                                WaveToRescale = RemoveEnding(WaveToRescale, "_RA")
1927                         endif
1928                WaveDataFolder = WaveString[0]
1929                SetDataFolder $WaveDataFolder
1930                if (stringmatch(WaveToRescale, "*_q"))
1931                xwave = WaveToRescale
1932                XRescale(xwave)
1933                elseif (stringmatch(WaveToRescale, "*_i"))
1934                ywave = WaveToRescale
1935                xwave = RemoveEnding(WaveToRescale, "_i")+"_q"
1936                YRescale(ywave, xwave)
1937                elseif (stringmatch(WaveToRescale, "*_s"))
1938                swave = WaveToRescale
1939                ywave = RemoveEnding(WaveToRescale, "_s")+"_i"
1940                xwave = RemoveEnding(WaveToRescale, "_s")+"_q"
1941                ERescale(swave, ywave, xwave)
1942                elseif (stringmatch(WaveToRescale, "xwave_*"))
1943                xwave=WaveToRescale
1944                XRescale(xwave)
1945                elseif (stringmatch(WaveToRescale, "ywave_*"))
1946                ywave = WaveToRescale
1947                xwave= ReplaceString("ywave", WaveToRescale, "xwave")
1948                YRescale(ywave, xwave)
1949                elseif(stringmatch(WaveToRescale, "*_qvals"))
1950                xwave = WaveToRescale
1951                XRescale(xwave)
1952                elseif(stringmatch(WaveToRescale, "smeared*") && stringmatch(WaveToRescale, "!*_qvals"))
1953                ywave = WaveToRescale
1954                                for (k=1; k < numpnts(WaveString); k+=1)
1955                                        if (stringmatch(Wavestring[k], "*_qvals"))
1956                                                xwave = Wavestring[k]
1957                                        endif
1958                                endfor
1959                YRescale(ywave, xwave)
1960                else
1961                ywave = WaveToRescale
1962                        for (k=1; k < numpnts(WaveString); k+=1)
1963                                if (stringmatch(Wavestring[k], "*_q"))
1964                                        xwave = Wavestring[k]
1965                                endif
1966                        endfor
1967                YRescale(ywave,xwave)
1968                string yAxis = ywave+"_RA"
1969                wave yAxisWave = $yAxis
1970                SetFormula yAxisWave, "YRescale(ywave,xwave)"
1971                endif
1972                SetDataFolder root:Packages:NIST:RescaleAxis
1973                endfor
1974        endfor
1975       
1976        string oldywave, xstr, ystr
1977        for (i = 0; i < ItemsInList(listWave,";"); i+=1)
1978                temp = StringFromList(i,listWave,";")
1979                Wave/T WaveString = $temp
1980                for (j=1; j < numpnts(WaveString); j+=1)
1981                         WaveToRescale = Wavestring[j]
1982                WaveDataFolder = WaveString[0]
1983                SetDataFolder $WaveDataFolder
1984                ControlInfo/W=RescaleAxisPanel yModel
1985                ystr = S_Value
1986                ControlInfo/W=RescaleAxisPanel xModel
1987                xstr = S_Value
1988                        if(cmpstr("I",ystr)==0 && cmpstr("q",xstr)==0)
1989                                if(stringmatch(WaveToRescale, "*_i_RA"))
1990                                        oldywave = WaveToRescale
1991                                        ywave = RemoveEnding(WaveToRescale,"_RA")
1992                                        xwave = RemoveEnding(WaveToRescale, "_i_RA")+"_q"
1993                                        replacewave/Y/W=$topGraph trace=$oldywave, $ywave
1994                                        replacewave/X/W=$topGraph trace=$ywave, $xwave
1995                                        swave = RemoveEnding(WaveToRescale, "_i_RA")+"_s"
1996                                        if(exists(swave)==1)
1997                                                ErrorBars/T=0/W=$topGraph $ywave, Y wave=($swave,$swave)       
1998                                        endif
1999                                elseif (stringmatch(WaveToRescale,  "smeared*"))
2000                                        if(stringmatch(WaveToRescale,"*_RA") && stringmatch(WaveToRescale,"!*_qvals*") )
2001                                                oldywave = WaveToRescale
2002                                                ywave = RemoveEnding(WaveToRescale,"_RA")
2003                                                xwave = "smeared_qvals"
2004                                                replacewave/Y/W=$topGraph trace=$oldywave, $ywave
2005                                                replacewave/X/W=$topGraph trace=$ywave, $xwave
2006                                        endif
2007                                elseif(stringmatch(WaveToRescale,"ywave*") && stringmatch(WaveToRescale,"*_RA"))
2008                                        oldywave = WaveToRescale
2009                                        ywave = RemoveEnding(WaveToRescale,"_RA")
2010                                        xwave = ReplaceString("ywave",ywave,"xwave")
2011                                        replacewave/Y/W=$topGraph trace=$oldywave, $ywave
2012                                        replacewave/X/W=$topGraph trace=$ywave, $xwave                                 
2013                                elseif(stringmatch(WaveToRescale, "*FitYw*") && stringmatch(WaveToRescale, "*_RA"))
2014                                        oldywave = WaveToRescale
2015                                        ywave = RemoveEnding(WaveToRescale,"_RA")
2016                                        for (k=1; k < numpnts(WaveString); k+=1)
2017                                                if (stringmatch(Wavestring[k], "*_q"))
2018                                                        xwave = Wavestring[k]
2019                                                endif
2020                                        endfor
2021                                        replacewave/Y/W=$topGraph trace=$oldywave, $ywave
2022                                        replacewave/X/W=$topGraph trace=$ywave, $xwave 
2023                                endif                   
2024                        elseif(stringmatch(WaveToRescale, "*_RA"))
2025                        elseif (stringmatch(WaveToRescale, "*_i"))
2026                                DoWindow/F topGraph
2027                                oldywave = WaveToRescale
2028                                xwave = RemoveEnding(WaveToRescale, "_i")+"_q_RA"
2029                                ywave = WaveToRescale + "_RA"
2030                                replacewave/Y/W=$topGraph trace=$oldywave, $ywave
2031                                replacewave/X/W=$topGraph trace=$ywave, $xwave
2032                                ModifyGraph log=0
2033                                swave = RemoveEnding(WaveToRescale, "_i")+"_s_RA"
2034                                if(exists(swave)==1)
2035                                        ErrorBars/T=0/W=$topGraph $ywave, Y wave=($swave,$swave)       
2036                                endif
2037                                DoUpdate       
2038                        elseif(stringmatch(WaveToRescale, "smeared*") && stringmatch(WaveToRescale, "!*_qvals"))
2039                                oldywave = WaveToRescale
2040                                ywave = WaveToRescale + "_RA"
2041                                replacewave/Y/W=$topGraph trace=$oldywave, $ywave
2042                                xwave = "smeared_qvals_RA"
2043                                replacewave/X/W=$topGraph trace=$ywave, $xwave 
2044                        elseif(stringmatch(WaveToRescale,"ywave*"))
2045                                oldywave = WaveToRescale
2046                                ywave = WaveToRescale + "_RA"
2047                                xwave = ReplaceString("ywave",ywave,"xwave")
2048                                replacewave/Y/W=$topGraph trace=$oldywave, $ywave
2049                                replacewave/X/W=$topGraph trace=$ywave, $xwave                                 
2050                        elseif(stringmatch(WaveToRescale, "*FitYw*"))
2051                                oldywave = WaveToRescale
2052                                ywave = WaveToRescale+"_RA"
2053                                for (k=1; k < numpnts(WaveString); k+=1)
2054                                        if (stringmatch(Wavestring[k], "*_q"))
2055                                                xwave = Wavestring[k]+"_RA"
2056                                        endif
2057                                endfor
2058                                replacewave/Y/W=$topGraph trace=$oldywave, $ywave
2059                                replacewave/X/W=$topGraph trace=$ywave, $xwave 
2060                        endif
2061                        SetDataFolder root:Packages:NIST:RescaleAxis
2062                        DoUpdate
2063                endfor
2064        endfor
2065        KillWaves/A/Z
2066               
2067        string ylabel, xlabel
2068        ControlInfo/W=RescaleAxisPanel yModel
2069        ystr = S_Value
2070        ControlInfo/W=RescaleAxisPanel xModel
2071        xstr = S_Value
2072       
2073        if(cmpstr("I",ystr)==0 && cmpstr("q",xstr)==0)
2074                modifygraph log=1
2075        else
2076                modifygraph log=0
2077        endif
2078       
2079        Variable pow_a,pow_b,pow_c
2080        ControlInfo/W=RescaleAxisPanel expa
2081        pow_a = V_value
2082        ControlInfo/W=RescaleAxisPanel expb
2083        pow_b = V_value
2084        ControlInfo/W=RescaleAxisPanel expc
2085        pow_c = V_value
2086       
2087        If (cmpstr("I",ystr) == 0)
2088                ylabel = "I(q)"
2089        elseif (cmpstr("ln(I)",ystr) == 0)
2090                ylabel = "ln(I)"
2091        elseif (cmpstr("log(I)",ystr) == 0)
2092                ylabel = "log(I)"
2093        elseif (cmpstr("1/I",ystr) == 0)
2094                ylabel = "1/I"
2095        elseif (cmpstr("I^a",ystr) == 0)
2096                ylabel = "I\S"+num2str(pow_a)+"\M"
2097        elseif (cmpstr("Iq^a",ystr) == 0)
2098                ylabel = "Iq\S"+num2str(pow_a)+"\M"
2099        elseif (cmpstr("I^a q^b",ystr) == 0)
2100                ylabel = "I\S"+num2str(pow_a)+"\Mq\S"+num2str(pow_b)+"\M"
2101        elseif (cmpstr("1/sqrt(I)",ystr) == 0)
2102                ylabel = "1/sqrt(I)"
2103        elseif (cmpstr("ln(Iq)",ystr) == 0)
2104                ylabel = "ln(Iq)"
2105        elseif (cmpstr("ln(Iq^2)",ystr) == 0)
2106                ylabel = "ln(Iq\S2\M)"
2107        endif
2108
2109        If (cmpstr("q",xstr) == 0)
2110                xlabel = "q (A\S-1\M)"
2111        elseif (cmpstr("q^2",xstr) == 0)
2112                xlabel = "q\S2\M"
2113        elseif (cmpstr("log(q)",xstr) == 0)
2114                xlabel = "log(q)"
2115        elseif (cmpstr("q^c",xstr) == 0)
2116                xlabel = "q\S"+num2str(pow_c)+"\M"
2117        endif
2118       
2119        SetAxis/A
2120        Label left ylabel
2121        Label bottom xlabel
2122       
2123        SetDataFolder root:
2124End
2125
2126Function YRescale(ywave, xwave)
2127        String ywave,xwave
2128 
2129        Wave yw = $ywave
2130        Wave xw = $xwave
2131       
2132        //Scaling exponents and background value
2133        Variable pow_a,pow_b,pow_c
2134        ControlInfo/W=RescaleAxisPanel expa
2135        pow_a = V_value
2136        ControlInfo/W=RescaleAxisPanel expb
2137        pow_b = V_value
2138        ControlInfo/W=RescaleAxisPanel expc
2139        pow_c = V_value
2140       
2141        //check for physical limits on exponent values
2142        // if bad values found, alert, and reset to good values so the rescaling can continue
2143        NVAR gA = root:Packages:NIST:RescaleAxis:gRAExpA
2144        NVAR gB = root:Packages:NIST:RescaleAxis:gRAExpB
2145        NVAR gC = root:Packages:NIST:RescaleAxis:gRAExpC
2146        if((pow_a < -2) || (pow_a > 10))
2147                DoAlert 0,"Exponent a must be in the range (-2,10) - the exponent a has been reset to 1"
2148                gA = 1
2149        endif
2150        if((pow_b < 0) || (pow_b > 10))
2151                DoAlert 0,"Exponent b must be in the range (0,10) - the exponent b has been reset to 1"
2152                gB = 1
2153        endif
2154        //if q^c is the x-scaling, c must be be within limits and also non-zero
2155        ControlInfo/W=RescaleAxisPanel xModel
2156        If (cmpstr("q^c",S_Value) == 0)
2157                if(pow_c == 0)
2158                        DoAlert 0,"Exponent c must be non-zero, c has been reset to 1"
2159                        gC = 1
2160                endif
2161                if((pow_c < -10) || (pow_c > 10))
2162                        DoAlert 0,"Exponent c must be in the range (-10,10), c has been reset to 1"
2163                        gC = 1
2164                endif
2165        endif
2166       
2167        //variables set for each model to control look of graph
2168        String ystr, yAxis
2169        //check for proper y-scaling selection, make the necessary waves
2170//      Wave yAxisWave
2171
2172        ControlInfo/W=RescaleAxisPanel yModel
2173        ystr = S_Value
2174       
2175        do
2176                If (cmpstr("I",S_Value) == 0)
2177                        yAxis = ywave+"_RA"
2178                        if (exists(yAxis)== 0)
2179                                Duplicate yw $yAxis
2180                        endif
2181                        SetScale d 0,0,"1/cm",$yAxis
2182                        wave yAxisWave = $yAxis
2183                        yAxisWave = yw
2184                        break   
2185                endif
2186                If (cmpstr("ln(I)",S_Value) == 0)
2187                        yAxis = ywave+"_RA"
2188                        if (exists(yAxis)== 0)
2189                                Duplicate yw $yAxis
2190                        endif
2191                        SetScale d 0,0,"",$yAxis
2192                        wave yAxisWave = $yAxis
2193                        yAxisWave = ln(yw)
2194                        break   
2195                endif
2196                If (cmpstr("log(I)",S_Value) == 0)
2197                        yAxis = ywave+"_RA"
2198                        if (exists(yAxis)== 0)
2199                                Duplicate yw $yAxis
2200                        endif
2201                        SetScale d 0,0,"",$yAxis
2202                        wave yAxisWave = $yAxis
2203                        yAxisWave = log(yw)
2204                        break   
2205                endif
2206                If (cmpstr("1/I",S_Value) == 0)
2207                        yAxis = ywave+"_RA"
2208                        if (exists(yAxis)== 0)
2209                                Duplicate yw $yAxis
2210                        endif
2211                        SetScale d 0,0,"",$yAxis
2212                        wave yAxisWave = $yAxis
2213                        yAxisWave = 1/(yw)
2214                        break
2215                endif
2216                If (cmpstr("I^a",S_Value) == 0)
2217                        yAxis = ywave+"_RA"
2218                        if (exists(yAxis)== 0)
2219                                Duplicate yw $yAxis
2220                        endif
2221                        SetScale d 0,0,"",$yAxis
2222                        wave yAxisWave = $yAxis
2223                        yAxisWave = yw^pow_a
2224                        break
2225                endif
2226                If (cmpstr("Iq^a",S_Value) == 0)
2227                        yAxis = ywave+"_RA"
2228                        if (exists(yAxis)== 0)
2229                                Duplicate yw $yAxis
2230                        endif
2231                        SetScale d 0,0,"",$yAxis
2232                        wave yAxisWave = $yAxis
2233                        yAxisWave = yw*xw^pow_a
2234                        break
2235                endif
2236                If (cmpstr("I^a q^b",S_Value) == 0)
2237                        yAxis = ywave+"_RA"
2238                        if (exists(yAxis)== 0)
2239                                Duplicate yw $yAxis
2240                        endif
2241                        SetScale d 0,0,"",$yAxis
2242                        wave yAxisWave = $yAxis
2243                        yAxisWave = yw^pow_a*xw^pow_b
2244                        break
2245                endif
2246                If (cmpstr("1/sqrt(I)",S_Value) == 0)
2247                        yAxis = ywave+"_RA"
2248                        if (exists(yAxis)== 0)
2249                                Duplicate yw $yAxis
2250                        endif
2251                        SetScale d 0,0,"",$yAxis
2252                        wave yAxisWave = $yAxis
2253                        yAxisWave = 1/sqrt(yw)
2254                        break
2255                endif
2256                If (cmpstr("ln(Iq)",S_Value) == 0)
2257                        yAxis = ywave+"_RA"
2258                        if (exists(yAxis)== 0)
2259                                Duplicate yw $yAxis
2260                        endif
2261                        SetScale d 0,0,"",$yAxis
2262                        wave yAxisWave = $yAxis
2263                        yAxisWave = ln(xw*yw)
2264                        break
2265                endif
2266                If (cmpstr("ln(Iq^2)",S_Value) == 0)
2267                        yAxis = ywave+"_RA"
2268                        if (exists(yAxis)== 0)
2269                                Duplicate yw $yAxis
2270                        endif
2271                        SetScale d 0,0,"",$yAxis
2272                        wave yAxisWave = $yAxis
2273                        yAxisWave = ln(xw*xw*yw)
2274                        break
2275                endif
2276                //more ifs for each case
2277               
2278                // if selection not found, abort
2279                DoAlert 0,"Y-axis scaling incorrect. Aborting"
2280                Abort
2281        while(0)
2282End
2283
2284Function XRescale(xwave)       
2285        String xwave
2286 
2287        Wave xw = $xwave
2288                 
2289        //Scaling exponents and background value
2290        Variable pow_a,pow_b,pow_c
2291        ControlInfo/W=RescaleAxisPanel expa
2292        pow_a = V_value
2293        ControlInfo/W=RescaleAxisPanel expb
2294        pow_b = V_value
2295        ControlInfo/W=RescaleAxisPanel expc
2296        pow_c = V_value
2297       
2298//check for physical limits on exponent values
2299// if bad values found, alert, and reset to good values so the rescaling can continue
2300        NVAR gA = root:Packages:NIST:RescaleAxis:gRAExpA
2301        NVAR gB = root:Packages:NIST:RescaleAxis:gRAExpB
2302        NVAR gC = root:Packages:NIST:RescaleAxis:gRAExpC
2303        if((pow_a < -2) || (pow_a > 10))
2304                DoAlert 0,"Exponent a must be in the range (-2,10) - the exponent a has been reset to 1"
2305                gA = 1
2306        endif
2307        if((pow_b < 0) || (pow_b > 10))
2308                DoAlert 0,"Exponent b must be in the range (0,10) - the exponent b has been reset to 1"
2309                gB = 1
2310        endif
2311        //if q^c is the x-scaling, c must be be within limits and also non-zero
2312        ControlInfo/W=RescaleAxisPanel xModel
2313        If (cmpstr("q^c",S_Value) == 0)
2314                if(pow_c == 0)
2315                        DoAlert 0,"Exponent c must be non-zero, c has been reset to 1"
2316                        gC = 1
2317                endif
2318                if((pow_c < -10) || (pow_c > 10))
2319                        DoAlert 0,"Exponent c must be in the range (-10,10), c has been reset to 1"
2320                        gC = 1
2321                endif
2322        endif
2323       
2324        //variables set for each model to control look of graph
2325        String xstr, xAxis
2326        //check for proper y-scaling selection, make the necessary waves
2327//      Wave xAxisWave
2328
2329        ControlInfo/W=RescaleAxisPanel xModel
2330        xstr = S_Value
2331        do
2332                // make the new yaxis wave
2333                If (cmpstr("q",S_Value) == 0)   
2334                        xAxis = xwave+"_RA"
2335                        if (exists(xAxis)== 0)
2336                                Duplicate xw $xAxis
2337                        endif
2338                        SetScale d 0,0,"A^-1",$xAxis
2339                        wave xAxisWave = $xAxis
2340                        xAxisWave = xw
2341                        break   
2342                endif
2343                If (cmpstr("q^2",S_Value) == 0)
2344                        xAxis = xwave+"_RA"
2345                        if (exists(xAxis)== 0)
2346                                Duplicate xw $xAxis
2347                        endif
2348                        SetScale d 0,0,"A^-2",$xAxis
2349                        wave xAxisWave = $xAxis
2350                        xAxisWave = xw*xw
2351                        break   
2352                endif
2353                If (cmpstr("log(q)",S_Value) == 0)     
2354                        xAxis = xwave+"_RA"
2355                        if (exists(xAxis)== 0)
2356                                Duplicate xw $xAxis
2357                        endif
2358                        SetScale d 0,0,"",$xAxis
2359                        wave xAxisWave = $xAxis
2360                        xAxisWave = log(xw)
2361                        break   
2362                endif
2363                If (cmpstr("q^c",S_Value) == 0)
2364                        xAxis = xwave+"_RA"
2365                        if (exists(xAxis)== 0)
2366                                Duplicate xw $xAxis
2367                        endif
2368                        SetScale d 0,0,"", $xAxis
2369                        wave xAxisWave = $xAxis
2370                        xAxisWave = xw^pow_c
2371                        break
2372                endif
2373       
2374                //more ifs for each case
2375                // if selection not found, abort
2376                DoAlert 0,"X-axis scaling incorrect. Aborting"
2377                Abort
2378        while(0)        //end of "case" statement for x-axis scaling
2379End
2380
2381Function ERescale(swave, ywave, xwave) 
2382        String swave, ywave, xwave
2383 
2384        Wave ew = $swave
2385        Wave yw = $ywave
2386        Wave xw = $xwave
2387                 
2388        //Scaling exponents and background value
2389        Variable pow_a,pow_b,pow_c
2390        ControlInfo/W=RescaleAxisPanel expa
2391        pow_a = V_value
2392        ControlInfo/W=RescaleAxisPanel expb
2393        pow_b = V_value
2394        ControlInfo/W=RescaleAxisPanel expc
2395        pow_c = V_value
2396       
2397//check for physical limits on exponent values
2398// if bad values found, alert, and reset to good values so the rescaling can continue
2399        NVAR gA = root:Packages:NIST:RescaleAxis:gRAExpA
2400        NVAR gB = root:Packages:NIST:RescaleAxis:gRAExpB
2401        NVAR gC = root:Packages:NIST:RescaleAxis:gRAExpC
2402        if((pow_a < -2) || (pow_a > 10))
2403                DoAlert 0,"Exponent a must be in the range (-2,10) - the exponent a has been reset to 1"
2404                gA = 1
2405        endif
2406        if((pow_b < 0) || (pow_b > 10))
2407                DoAlert 0,"Exponent b must be in the range (0,10) - the exponent b has been reset to 1"
2408                gB = 1
2409        endif
2410        //if q^c is the x-scaling, c must be be within limits and also non-zero
2411        ControlInfo/W=RescaleAxisPanel xModel
2412        If (cmpstr("q^c",S_Value) == 0)
2413                if(pow_c == 0)
2414                        DoAlert 0,"Exponent c must be non-zero, c has been reset to 1"
2415                        gC = 1
2416                endif
2417                if((pow_c < -10) || (pow_c > 10))
2418                        DoAlert 0,"Exponent c must be in the range (-10,10), c has been reset to 1"
2419                        gC = 1
2420                endif
2421        endif
2422       
2423        //variables set for each model to control look of graph
2424        String ystr, eWave
2425        //check for proper y-scaling selection, make the necessary waves
2426//      Wave yErrWave
2427
2428        ControlInfo/W=RescaleAxisPanel yModel
2429        ystr = S_Value
2430        do
2431               
2432                If (cmpstr("I",S_Value) == 0)
2433                        eWave = swave+"_RA"
2434                        if (exists(eWave) == 0)
2435                                Duplicate ew $eWave
2436                        endif
2437                        wave yErrWave = $eWave
2438                        yErrWave = ew
2439                        break   
2440                endif
2441                If (cmpstr("ln(I)",S_Value) == 0)
2442                        eWave = swave+"_RA"
2443                        if (exists(eWave) == 0)
2444                                Duplicate ew $eWave
2445                        endif
2446                        wave yErrWave = $eWave
2447                        yErrWave = ew/yw
2448                        break   
2449                endif
2450                If (cmpstr("log(I)",S_Value) == 0)
2451                        eWave = swave+"_RA"
2452                        if (exists(eWave) == 0)
2453                                Duplicate ew $eWave
2454                        endif
2455                        wave yErrWave = $eWave
2456                        yErrWave = ew/(2.30*yw)
2457                        break   
2458                endif
2459                If (cmpstr("1/I",S_Value) == 0)
2460                        eWave = swave+"_RA"
2461                        if (exists(eWave) == 0)
2462                                Duplicate ew $eWave
2463                        endif
2464                        wave yErrWave = $eWave
2465                        yErrWave = ew/(yw^2)
2466                        break
2467                endif
2468                If (cmpstr("I^a",S_Value) == 0)
2469                        eWave = swave+"_RA"
2470                        if (exists(eWave) == 0)
2471                                Duplicate ew $eWave
2472                        endif
2473                        wave yErrWave = $eWave
2474                        yErrWave = ew*abs(pow_a*(yw^(pow_a-1)))
2475                        break
2476                endif
2477                If (cmpstr("Iq^a",S_Value) == 0)
2478                        eWave = swave+"_RA"
2479                        if (exists(eWave) == 0)
2480                                Duplicate ew $eWave
2481                        endif
2482                        wave yErrWave = $eWave
2483                        yErrWave = ew*xw^pow_a
2484                        break
2485                endif
2486                If (cmpstr("I^a q^b",S_Value) == 0)
2487                        eWave = swave+"_RA"
2488                        if (exists(eWave) == 0)
2489                                Duplicate ew $eWave
2490                        endif
2491                        wave yErrWave = $eWave
2492                        yErrWave = ew*abs(pow_a*(yw^(pow_a-1)))*xw^pow_b
2493                        break
2494                endif
2495                If (cmpstr("1/sqrt(I)",S_Value) == 0)
2496                        eWave = swave+"_RA"
2497                        if (exists(eWave) == 0)
2498                                Duplicate ew $eWave
2499                        endif
2500                        wave yErrWave = $eWave
2501                        yErrWave = 0.5*ew*yw^(-1.5)
2502                        break
2503                endif
2504                If (cmpstr("ln(Iq)",S_Value) == 0)
2505                        eWave = swave+"_RA"
2506                        if (exists(eWave) == 0)
2507                                Duplicate ew $eWave
2508                        endif
2509                        wave yErrWave = $eWave
2510                        yErrWave =ew/yw
2511                        break
2512                endif
2513                If (cmpstr("ln(Iq^2)",S_Value) == 0)
2514                        eWave = swave+"_RA"
2515                        if (exists(eWave) == 0)
2516                                Duplicate ew $eWave
2517                        endif
2518                        wave yErrWave = $eWave
2519                        yErrWave = ew/yw
2520                        break
2521                endif
2522                //more ifs for each case
2523               
2524                // if selection not found, abort
2525                DoAlert 0,"Y-axis scaling incorrect. Aborting"
2526                Abort
2527        while(0)        //end of "case" statement for y-axis scaling
2528
2529End
2530
2531///////////////////////////
2532
Note: See TracBrowser for help on using the repository browser.