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

Last change on this file since 876 was 876, checked in by matthew.was, 10 years ago

Updated the RA Panel to include a help button

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