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

Last change on this file since 743 was 743, checked in by srkline, 12 years ago

ticket #281: added a check for SAM and EMP data to both be present when updating the USANS transmission. An alert is presented if one or the other is missing.

ticket #194: added two more options for curve fitting information. users can no with checkboxes add residuals to the fit graph, and add a textbox of fit information. unchecking the boxes provides the option for removing them from the graph.

-- still need to make sure that the residuals stay in sync. if they are on the graph and then use is un-selected, the residual won't update with the new fit. The textbox is fine - it's automatically killed if not selected.

File size: 42.1 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=4.10
3#pragma IgorVersion=6.1
4
5
6//Macro OpenWrapperPanel()
7//      Init_WrapperPanel()
8//End
9
10Function Init_WrapperPanel()
11
12        if(itemsinlist(WinList("SA_includes_v400.ipf", ";","INCLUDE:6"),";") != 0)
13                //must be opening a v4.00 or earlier template
14                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"
15        endif
16       
17        //make sure that folders exist - this is the first initialization to be called
18        NewDataFolder/O root:Packages
19        NewDataFolder/O root:Packages:NIST
20
21        //Create useful globals
22        Variable/G root:Packages:NIST:SANS_ANA_VERSION=4.10
23        String/G root:Packages:NIST:SANS_ANA_EXTENSION="_v40"
24        //Set this variable to 1 to force use of trapezoidal integration routine for USANS smearing
25        Variable/G root:Packages:NIST:USANSUseTrap = 0
26        Variable/G root:Packages:NIST:USANS_dQv = 0.117
27        Variable/G root:Packages:NIST:gUseGenCurveFit = 0                       //set to 1 to use genetic optimization
28                       
29        //Ugly. Put this here to make sure things don't break
30        String/G root:Packages:NIST:gXMLLoader_Title
31       
32       
33        //initializes preferences. this includes XML y/n, and SANS Reduction items.
34        // if they already exist, they won't be overwritten
35        Execute "Initialize_Preferences()"             
36       
37        DoWindow/F WrapperPanel
38        if(V_flag==0)
39                if(exists("root:Packages:NIST:coefKWStr")==0)
40                        String/G root:Packages:NIST:coefKWStr=""
41                endif
42                if(exists("root:Packages:NIST:suffixKWStr")==0)
43                        String/G root:Packages:NIST:suffixKWStr=""
44                endif
45                if(exists("root:Packages:NIST:paramKWStr")==0)
46                        String/G root:Packages:NIST:paramKWStr=""
47                endif
48                Execute "WrapperPanel()"
49        endif
50End
51
52////////
53//
54// if model is Smeared, search the DF for coefficients
55// if new DF chosen, need to reset
56// if new model function, need to reset table
57//
58// create hold_mod (0/1), constr_low_mod, constr_hi_mod
59// in either DF (smeared) or in root: (normal)
60// and put these in the table as needed
61//
62Window WrapperPanel()
63        PauseUpdate; Silent 1           // building window...
64        NewPanel /W=(459,44,1113,499)/N=wrapperPanel/K=1 as "Curve Fit Setup"
65        ModifyPanel fixedSize=1
66       
67        GroupBox grpBox_0,pos={18,11},size={390,113}
68        GroupBox grpBox_1,pos={426,10},size={207,113}
69        GroupBox grpBox_2 title="No Fit",pos={10,130},size={0,0},frame=1,fSize=10,fstyle=1,fColor=(39321,1,1)
70        GroupBox grpBox_3 title="",pos={10,150},size={0,0},frame=1,fSize=10,fstyle=1,fColor=(39321,1,1)
71
72        Button button_1,pos={280,57},size={120,20},proc=PlotModelFunction,title="Plot 1D Function"
73        Button button_2,pos={300,93},size={100,20},proc=AppendModelToTarget,title="Append 1D"
74        Button button_3,pos={300,20},size={100,20},proc=W_LoadDataButtonProc,title="Load 1D Data"
75        PopupMenu popup_0,pos={30,21},size={218,20},title="Data Set",proc=DataSet_PopMenuProc
76        PopupMenu popup_0,mode=1,value= #"W_DataSetPopupList()"
77        PopupMenu popup_1,pos={30,57},size={136,20},title="Function"
78        PopupMenu popup_1,mode=1,value= #"W_FunctionPopupList()",proc=Function_PopMenuProc
79        PopupMenu popup_2,pos={30,93},size={123,20},title="Coefficients"
80        PopupMenu popup_2,mode=1,value= #"W_CoefPopupList()",proc=Coef_PopMenuProc
81        CheckBox check_0,pos={430,19},size={79,14},title="Use Cursors?",value= 0
82        CheckBox check_0,proc=UseCursorsWrapperProc
83        CheckBox check_1,pos={430,42},size={74,14},title="Use Epsilon?",value= 0
84        CheckBox check_2,pos={430,65},size={95,14},title="Use Constraints?",value= 0
85        CheckBox check_3,pos={530,18},size={72,14},title="2D Functions?",value= 0
86        CheckBox check_3 proc=Toggle2DControlsCheckProc
87        CheckBox check_4,pos={430,85},size={72,14},title="Report?",value= 0
88        CheckBox check_5,pos={444,103},size={72,14},title="Save it?",value= 0
89        CheckBox check_6,pos={530,42},size={72,14},title="Use Residuals?",value= 0
90        CheckBox check_6,proc=UseResidualsCheckProc
91        CheckBox check_7,pos={530,65},size={72,14},title="Info Box?",value= 0
92        CheckBox check_7,proc=UseInfoTextBoxCheckProc
93        //change draw order to put button over text of checkbox
94        Button button_0,pos={520,93},size={100,20},proc=DoTheFitButton,title="Do 1D Fit"
95        Button button_4,pos={520,126},size={100,20},proc=FeedbackButtonProc,title="Feedback"
96        Button button_5,pos={520,150},size={100,20},proc=FitHelpButtonProc,title="Help"
97
98        Edit/W=(20,174,634,435)/HOST=# 
99        ModifyTable width(Point)=0
100        RenameWindow #,T0
101        SetActiveSubwindow ##
102EndMacro
103
104//open the Help file for the Fit Manager
105Function FitHelpButtonProc(ba) : ButtonControl
106        STRUCT WMButtonAction &ba
107
108        switch( ba.eventCode )
109                case 2: // mouse up
110                        // click code here
111                        DisplayHelpTopic/Z/K=1 "Fit Manager"
112                        if(V_flag !=0)
113                                DoAlert 0,"The Fit Manager Help file could not be found"
114                        endif
115                        break
116        endswitch
117
118        return 0
119End
120
121
122//open the trac page for feedback
123Function FeedbackButtonProc(ba) : ButtonControl
124        STRUCT WMButtonAction &ba
125
126        switch( ba.eventCode )
127                case 2: // mouse up
128                        // click code here
129                        OpenTracTicketPage()
130                        break
131        endswitch
132
133        return 0
134End
135
136
137//obvious use, now finds the most recent data loaded, finds the folder, and pops the menu with that selection...
138//
139Function W_LoadDataButtonProc(ba) : ButtonControl
140        STRUCT WMButtonAction &ba
141
142        switch( ba.eventCode )
143                case 2: // mouse up
144                        // click code here
145                        String  topGraph= WinName(0,1)
146                        if(strlen(topGraph) != 0)
147                                DoWindow/F $topGraph                    //so that the panel is not on top
148                        endif
149                        Execute "A_LoadOneDData()"
150                       
151                        ControlUpdate/W=WrapperPanel popup_0
152                        //instead of a simple controlUpdate, better to pop the menu to make sure that the other menus follow
153                        // convoluted method to find the right item and pop the menu.
154
155                        // data is plotted, so get the "new" top graph
156                        topGraph= WinName(0,1)  //this is the topmost graph, and should exist, but...
157                        if(cmpstr(topGraph,"")==0)
158                                return(0)
159                        endif
160                        String list,folderStr
161                        Variable num
162                        list = TraceNameList(topGraph,";",1)            //want the last item in the list
163                        num= ItemsInList(list)
164                        FolderStr = StringFromList(num-1,list,";")
165                        folderStr = folderStr[0,strlen(folderStr)-3]            //remove the "_i" that the loader enforced
166                        list = W_DataSetPopupList()
167                        num=WhichListItem(folderStr,list,";",0,0)
168                        if(num != -1)
169                                PopupMenu popup_0,mode=num+1,win=WrapperPanel
170                                ControlUpdate/W=WrapperPanel popup_0
171                               
172                                // fake mouse up to pop the menu
173                                Struct WMPopupAction ps
174                                ps.eventCode = 2                //fake mouse up
175                                DataSet_PopMenuProc(ps)
176                        endif
177                        break
178        endswitch
179       
180        return 0
181End
182
183
184// is there a simpler way to do this? I don't think so.
185Function/S W_DataSetPopupList()
186
187        String str=GetAList(4)
188
189        if(strlen(str)==0)
190                str = "No data loaded"
191        endif
192        str = SortList(str)
193       
194        return(str)
195End
196
197
198// show the available models
199// not the f*(cw,xw) point calculations
200// not the *X(cw,xw) XOPS
201//
202// KIND:10 should show only user-defined curve fitting functions
203// - not XOPs
204// - not other user-defined functions
205Function/S W_FunctionPopupList()
206        String list,tmp
207        //get every user defined curve fit function, remove everything the user doesn't need to see...
208        list = User_FunctionPopupList()         
209
210        if(strlen(list)==0)
211                list = "No functions plotted"
212        endif
213       
214        list = SortList(list)
215        return(list)
216End
217
218
219// show all the appropriate coefficient waves
220//
221// also need to search the folder listed in "data set" popup
222// for smeared coefs
223//
224// - or - restrict the coefficient list based on the model function
225// - new way, filter the possible values based on the data folder and function
226Function/S W_CoefPopupList()
227
228        String notPlotted="Please plot the function"
229        ControlInfo/W=wrapperpanel popup_1
230        String funcStr=S_Value
231        String coefStr=getFunctionCoef(funcStr)
232       
233        if(cmpstr(coefStr,"")==0)               //no correspondence in the KW string
234                return(notPlotted)
235        endif
236       
237       
238        //found a coefficient wave - only two places to look
239        // is it in the root folder?
240        if(exists("root:"+coefStr) != 0)
241                return(coefStr)
242        endif
243       
244        // is it in the data folder?
245        ControlInfo/W=wrapperpanel popup_0
246        String folderStr=S_Value
247        if(exists("root:"+folderStr+":"+coefStr) != 0)
248                return(coefStr)
249        endif
250
251        return(notPlotted)
252End
253
254// show all the appropriate coefficient waves
255//
256// also need to search the folder listed in "data set" popup
257// for smeared coefs
258//
259// - or - restrict the coefficient list based on the model function
260//
261// --old way
262//Function/S W_CoefPopupList()
263//      String list
264//      setDataFolder root:
265//      list = WaveList("coef*",";","")
266//     
267//      ControlInfo/W=wrapperpanel popup_0
268//      if(V_Value != 0)                //0== no items in menu
269//              if(DataFolderExists("root:"+S_Value))
270//                      SetDataFolder $("root:"+S_Value)
271//                      list += WaveList("*coef*",";","")
272//              endif
273//      endif
274//     
275//      // tmp coefficients that aren't being cleaned up from somewhere...
276//      list = RemoveFromList("temp_coef_1;temp_coef_2;", list  ,";")
277//
278//      if(strlen(list)==0)
279//              list = "No functions plotted"
280//      endif
281//      list = SortList(list)
282//     
283////    Print itemsinlist(list,";")
284//     
285//      setDataFolder root:
286//      return(list)
287//End
288
289// if the coefficients are changed, then update the table
290//
291//update the table
292// may be easier to just kill the subwindow (table) and create a new one
293// need to set/reset all of the waves in the table
294//
295// !! only respond to mouse up
296//
297Function Coef_PopMenuProc(pa) : PopupMenuControl
298        STRUCT WMPopupAction &pa
299
300        switch( pa.eventCode )
301                case 2: // mouse up
302                        Variable popNum = pa.popNum
303                        String popStr = pa.popStr
304                        ControlInfo/W=WrapperPanel popup_1
305                        String funcStr=S_Value
306                        String suffix = getModelSuffix(funcStr)
307                        ControlInfo/W=WrapperPanel popup_0
308                        String folderStr=S_Value
309                       
310                        if(cmpstr(popStr,"Please plot the function")==0)
311//                              Print "function not plotted"
312                                return(0)
313                        endif
314
315// this if/else/endif should not ever return an error alert     
316// it should simply set the data folder properly       
317                        if(DataFolderExists("root:"+folderStr))
318                                SetDataFolder $("root:"+folderStr)
319                                if(!exists(popStr))
320                                        // must be unsmeared model, work in the root folder
321                                        SetDataFolder root:                             
322                                        if(!exists(popStr))             //this should be fine if the coef filter is working, but check anyhow
323                                                DoAlert 0,"the coefficient and data sets do not match (1)"
324                                                return 0
325                                        endif
326                                endif
327                        else
328                                // must be unsmeared model, work in the root folder
329                                SetDataFolder root:     
330                                if(!exists(popStr))             //this should be fine if the coef filter is working, but check anyhow
331                                        DoAlert 0,"the coefficient and data sets do not match (2)"
332                                        return 0
333                                endif
334                        endif
335                       
336                        // farm the work out to another function?
337                        Variable num=numpnts($popStr)
338                        // make the necessary waves if they don't exist already
339                        if(exists("Hold_"+suffix) == 0)
340                                Make/O/D/N=(num) $("epsilon_"+suffix),$("Hold_"+suffix)
341                                Make/O/T/N=(num) $("LoLim_"+suffix),$("HiLim_"+suffix)
342                                Wave eps = $("epsilon_"+suffix)
343                                Wave coef=$popStr
344                                if(eps[0] == 0)         //if eps already if filled, don't change it
345                                        eps = abs(coef*1e-4) + 1e-10                    //default eps is proportional to the coefficients
346                                endif
347                        endif
348                        // default epsilon values, sometimes needed for the fit
349                       
350                        WAVE/T LoLim = $("LoLim_"+suffix)
351                        WAVE/T HiLim = $("HiLim_"+suffix)
352                       
353                        // clear the table (a subwindow)
354                        DoWindow/F WrapperPanel                         // ?? had to add this in during all of the cursor meddling...
355                        KillWindow wrapperPanel#T0
356                        Edit/W=(20,174,634,435)/HOST=wrapperPanel
357                        RenameWindow #,T0
358                        // get them onto the table
359                        // how do I get the parameter name?
360                        String param = getFunctionParams(funcStr)
361                        AppendtoTable/W=wrapperPanel#T0 $param,$(popStr)
362                        AppendToTable/W=wrapperPanel#T0 $("Hold_"+suffix),$("LoLim_"+suffix),$("HiLim_"+suffix),$("epsilon_"+suffix)
363                        ModifyTable/W=wrapperPanel#T0 width(Point)=0
364                       
365                        SetDataFolder root:
366                        break
367        endswitch
368
369        return 0
370End
371
372// if the Function is changed, then update the coef popup (if possible) and then the table (if possible)
373//
374// !! only respond to mouse up
375//
376Function Function_PopMenuProc(pa) : PopupMenuControl
377        STRUCT WMPopupAction &pa
378
379        switch( pa.eventCode )
380                case 2: // mouse up
381                        Variable popNum = pa.popNum
382                        String funcStr = pa.popStr
383                        String coefStr = W_CoefPopupList()
384                       
385//                      Print "coefStr = ",coefStr
386                       
387                        ControlInfo/W=WrapperPanel popup_0
388                        String folderStr=S_Value
389                       
390                        String listStr = W_CoefPopupList()
391                        Variable num=WhichListItem(coefStr, listStr, ";")
392                        String str=StringFromList(num, listStr  ,";")
393//                      print "str = ",str
394                        //set the item in the coef popup, and pop it
395                        PopupMenu popup_2 win=WrapperPanel,mode=(num+1)
396                       
397                        Struct WMPopupAction ps
398                        ps.eventCode = 2                //fake mouse up
399                        ps.popStr = str
400                        Coef_PopMenuProc(ps)
401                       
402                        SetDataFolder root:
403                        break
404        endswitch
405
406        return 0
407End
408
409// if the Data Set is changed, then update the function (if possible)
410// and the coef popup (if possible) and then the table (if possible)
411//
412// !! only respond to mouse up here, and simply send a fake mouse up
413// to the function pop, which will do what it can do
414//
415Function DataSet_PopMenuProc(pa) : PopupMenuControl
416        STRUCT WMPopupAction &pa
417       
418        switch( pa.eventCode )
419                case 2: // mouse up
420                        // make sure that the cursors are on/off appropriately
421                        // let the cursors checkbox decide what to do, sending the current state
422                        ControlInfo/W=WrapperPanel check_0
423                        STRUCT WMCheckboxAction cba
424                        cba.eventCode = 2
425                        cba.checked = V_Value
426                        UseCursorsWrapperProc(cba)
427                                       
428                        // then cascade the function/coefficient popups
429                        Struct WMPopupAction ps
430                        ps.eventCode = 2                //fake mouse up
431                        Function_PopMenuProc(ps)
432                       
433                        SetDataFolder root:
434                        break
435        endswitch
436
437        return 0
438End
439
440
441// always pass this the function string
442//
443// this is new in the 2009 release, so make sure that it generates itself as needed.
444// Two options: (1) search and construct as needed, ask for intervention if I need it.
445// (2) since I'm passed the function, try to replot it to re-run the function
446// to fill in the strings. (Being sure to save the coefficients)
447//
448// using method (1) to fill in what I need with no intervention
449//
450Function/S getFunctionParams(funcStr)
451        String funcStr
452
453        String paramStr=""
454        SVAR/Z listStr=root:Packages:NIST:paramKWStr
455
456        if(SVAR_Exists(listStr))
457                paramStr = StringByKey(funcStr, listStr  ,"=",";",0)
458                if(strlen(paramStr)!=0)                 //will drop out of loop if string can't be found
459                        return(paramStr)
460                endif
461        else    //global string does not exist, create it and fill it in
462                Variable/G root:Pacakges:NIST:gReconstructStrings = 1                   //coefficients old style and must be rebuilt too
463                String/G root:Packages:NIST:paramKWStr=""
464                SVAR/Z listStr=root:Packages:NIST:paramKWStr
465        endif   
466       
467        // find everything to rebuild only if the model has been plotted (if so, coefficients will exist)
468        String coef = getFunctionCoef(funcStr)
469        if(strlen(coef)==0)
470                //model not plotted, don't reconstruct, return null string
471                return(paramStr)
472        endif
473       
474        ///// NEED TO BE IN PROPER DATA FOLDER FOR SMEARED FUNCTIONS
475        // FUNCTION POP MENU WILL LOOK IN ROOT OTHERWISE
476        ControlInfo/W=WrapperPanel popup_0
477        String folderStr=S_Value
478        // this if/else/endif should not ever return an error alert     
479        // it should simply set the data folder properly       
480        if(Stringmatch(funcStr,"Smear*"))               //simple test for smeared function
481                if(DataFolderExists("root:"+folderStr))
482                        SetDataFolder $("root:"+folderStr)
483                else
484                        SetDataFolder root:
485                endif
486        else
487                SetDataFolder root:
488        endif
489       
490        // model was plotted, find the suffix to fill in the parameter wave
491        SVAR suffListStr=root:Packages:NIST:suffixKWStr
492        String suffix = StringByKey(coef, suffListStr  ,"=",";",0)
493       
494        String paramWave = WaveList("*par*"+suffix,"","TEXT:1")         //should be one wave name, no trailing semicolon
495        listStr += funcStr+"="+paramWave+";"
496
497        //now look it up again
498        paramStr = StringByKey(funcStr, listStr  ,"=",";",0)
499
500        return(paramStr)
501End
502
503// always pass this the function string
504//
505Function/S getFunctionCoef(funcStr)
506        String funcStr
507
508        SVAR listStr=root:Packages:NIST:coefKWStr
509        String coefStr = StringByKey(funcStr, listStr  ,"=",";",0)
510
511        return(coefStr)
512End
513
514// always pass this the Function string
515//
516// does NOT return the leading "_" as part of the suffix
517// may need to set the string correctly - so lost of messing around for back-compatibility
518Function/S getModelSuffix(funcStr)
519        String funcStr
520
521        SVAR listStr=root:Packages:NIST:suffixKWStr
522        String suffixStr = StringByKey(funcStr, listStr  ,"=",";",0)
523
524        if(strlen(suffixStr) !=0)               //found it, get out
525                return(suffixStr)
526        endif
527       
528        // was the model plotted?
529        String coef = getFunctionCoef(funcStr)
530        if(strlen(coef)==0)             
531                //nothing plotted
532                return("")
533        else
534                //plotted, find the coeff
535                String suffix = StringByKey(coef, ListStr  ,"=",";",0)
536       
537                // add to the suffix list in the new style, if it was found
538                if(strlen(suffix) !=0)
539                        listStr += funcStr+"="+suffix+";"
540                endif
541                return(suffix)
542        endif
543       
544        return("")
545End
546
547
548
549// - this is based on stringent "PlotNNN" naming requirements
550//
551//  ???
552// - how to kill the generated table and graph, that are not needed now
553//
554Function PlotModelFunction(ba) : ButtonControl
555        STRUCT WMButtonAction &ba
556
557        String folderStr,funcStr,coefStr,cmdStr=""
558        Variable useCursors,useEps,useConstr
559       
560        Variable killWhat=0             //kill nothing as default
561       
562        switch( ba.eventCode )
563                case 2: // mouse up
564                        ControlInfo/W=WrapperPanel popup_0
565                        folderStr=S_Value
566                       
567                        ControlInfo/W=WrapperPanel popup_1
568                        funcStr=S_Value
569                       
570                        // maybe nothing has been loaded yet...
571                        if(cmpstr(funcStr,"No functions plotted") == 0)
572                                break
573                        endif
574                       
575                        // check for smeared or smeared function
576                        if(stringmatch(funcStr, "Smear*" )==1)
577                                //it's a smeared model
578                                // check for the special case of RPA that has an extra parameter
579                                if(strsearch(funcStr, "RPAForm", 0 ,0) == -1)
580                                        sprintf cmdStr, "Plot%s(\"%s\")",funcStr,folderStr              //not RPA
581                                else
582                                        sprintf cmdStr, "Plot%s(\"%s\",)",funcStr,folderStr             //yes RPA, leave a comma for input
583                                endif
584                                killWhat = 1
585                        else
586                                // it's not,    don't kill the graph, just the table           
587                                sprintf cmdStr, "Plot%s()",funcStr
588                                killWhat = 2
589                        endif
590                       
591                        //Print cmdStr
592                        Execute cmdStr
593                       
594                        //pop the function menu to set the proper coefficients
595                        DoWindow/F WrapperPanel
596                        STRUCT WMPopupAction pa
597                        pa.popStr = funcStr
598                        pa.eventcode = 2
599                        Function_PopMenuProc(pa)
600       
601                        KillTopGraphAndTable(killWhat)          // crude
602       
603                        break
604        endswitch
605       
606        return 0
607End
608
609// passing 0 kills nothing
610// passing 1 kills the top graph and table
611// passing 2 kills the top table only
612//
613Function KillTopGraphAndTable(killwhat)
614        Variable killWhat
615       
616        String topGraph= WinName(0,1)   //this is the topmost graph     
617        String topTable= WinName(0,2)   //this is the topmost table
618
619        if(killWhat == 0)
620                return(0)
621        endif
622       
623        if(killWhat == 1)
624                KillWindow $topGraph
625                KillWindow $topTable
626        endif
627       
628        if(killWhat == 2)
629                KillWindow $topTable
630        endif
631       
632        return(0)
633End
634
635// How to bypass the step of plot and append?
636//
637// do it in two separate events
638//
639Function AppendModelToTarget(ba) : ButtonControl
640        STRUCT WMButtonAction &ba
641
642        String coefStr,suffix,yWStr,xWStr,folderStr,funcStr
643       
644        switch( ba.eventCode )
645                case 2: // mouse up                     
646                        ControlInfo/W=WrapperPanel popup_2
647                        coefStr=S_Value
648                       
649                        ControlInfo/W=WrapperPanel popup_1
650                        funcStr=S_Value
651                        suffix = getModelSuffix(funcStr)
652                       
653                        // check for smeared or smeared function
654                        if(stringmatch(coefStr, "smear*" )==1)
655                                //it's a smeared model
656                                ControlInfo/W=WrapperPanel popup_0
657                                folderStr=S_Value
658                                xWStr = "root:"+folderStr+":smeared_qvals"
659                                ywStr = "root:"+folderStr+":smeared_"+suffix
660                        else
661                                // it's not, so it's in the root folder
662                                xWStr = "xwave_"+suffix
663                                yWStr = "ywave_"+suffix
664                        endif
665                       
666                        Wave/Z yw = $yWStr
667                        Wave/Z xw = $xWStr
668                        if(WaveExists(yw) && WaveExists(xw))
669                                AppendtoGraph yw vs xw
670                        else
671                                DoAlert 0,"The selected model has not been plotted for the selected data set."
672                        endif
673                        break
674        endswitch
675       
676        return 0
677End
678
679
680// this should parse the panel and call the FitWrapper() function
681Function DoTheFitButton(ba) : ButtonControl
682        STRUCT WMButtonAction &ba
683
684        String folderStr,funcStr,coefStr
685        Variable useCursors,useEps,useConstr,useResiduals,useTextBox
686       
687        switch( ba.eventCode )
688                case 2: // mouse up
689                        ControlInfo/W=WrapperPanel popup_0
690                        folderStr=S_Value
691                       
692                        ControlInfo/W=WrapperPanel popup_1
693                        funcStr=S_Value
694                       
695                        ControlInfo/W=WrapperPanel popup_2
696                        coefStr=S_Value
697                       
698                        ControlInfo/W=WrapperPanel check_0
699                        useCursors=V_Value
700                        ControlInfo/W=WrapperPanel check_1
701                        useEps=V_Value
702                        ControlInfo/W=WrapperPanel check_2
703                        useConstr=V_Value
704                       
705                        ControlInfo/W=WrapperPanel check_6
706                        useResiduals=V_Value
707                       
708                        ControlInfo/W=WrapperPanel check_7
709                        useTextBox = V_Value
710                       
711                        if(!CheckFunctionAndCoef(funcStr,coefStr))
712                                DoAlert 0,"The coefficients and function type do not match. Please correct the selections in the popup menus."
713                                break
714                        endif
715                       
716                        FitWrapper(folderStr,funcStr,coefStr,useCursors,useEps,useConstr,useResiduals,useTextBox)
717                       
718                        //      DoUpdate (does not work!)
719                        //?? why do I need to force an update ??
720                        if(!exists("root:"+folderStr+":"+coefStr))
721                                Wave w=$coefStr
722                        else
723                                Wave w=$("root:"+folderStr+":"+coefStr) //smeared coefs in data folder
724                        endif
725                        w[0] += 1e-6
726                        w[0] -= 1e-6
727       
728                        break
729        endswitch
730       
731        return 0
732End
733
734Function CheckFunctionAndCoef(funcStr,coefStr)
735        String funcStr,coefStr
736       
737        SVAR listStr=root:Packages:NIST:coefKWStr
738        String properCoefStr = StringByKey(funcStr, listStr  ,"=",";",0)
739        if(cmpstr("",properCoefStr)==0)
740                return(0)               //false, no match found, so properCoefStr is returned null
741        endif
742        if(cmpstr(coefStr,properCoefStr)==0)
743                return(1)               //true, the coef is the correct match
744        endif
745        return(0)                       //false, wrong coef
746End
747
748/////////////////////////////////
749
750// wrapper to do the desired fit
751//
752// folderStr is the data folder for the desired data set
753//
754//
755Function FitWrapper(folderStr,funcStr,coefStr,useCursors,useEps,useConstr,useResiduals,useTextBox)
756        String folderStr,funcStr,coefStr
757        Variable useCursors,useEps,useConstr,useResiduals,useTextBox
758
759        String suffix=getModelSuffix(funcStr)
760       
761        SetDataFolder $("root:"+folderStr)
762        if(!exists(coefStr))
763                // must be unsmeared model, work in the root folder
764                SetDataFolder root:                             
765                if(!exists(coefStr))            //this should be fine if the coef filter is working, but check anyhow
766                        DoAlert 0,"the coefficient and data sets do not match"
767                        return 0
768                endif
769        endif
770               
771        WAVE cw=$(coefStr)     
772        Wave hold=$("Hold_"+suffix)
773        Wave/T lolim=$("LoLim_"+suffix)
774        Wave/T hilim=$("HiLim_"+suffix)
775       
776        if(useEps)
777                Wave eps=$("epsilon_"+suffix)
778        endif
779// fill a struct instance whether I need one or not
780        String DF="root:"+folderStr+":"
781       
782        Struct ResSmearAAOStruct fs
783        WAVE/Z resW = $(DF+folderStr+"_res")                    //these may not exist, if 3-column data is used
784        WAVE/Z fs.resW =  resW
785        WAVE yw=$(DF+folderStr+"_i")
786        WAVE xw=$(DF+folderStr+"_q")
787        WAVE sw=$(DF+folderStr+"_s")
788        Wave fs.coefW = cw
789        Wave fs.yW = yw
790        Wave fs.xW = xw
791       
792        Duplicate/O yw $(DF+"FitYw")
793        WAVE fitYw = $(DF+"FitYw")
794        fitYw = NaN
795       
796        Variable useRes=0,isUSANS=0,val
797        if(stringmatch(funcStr, "Smear*"))              // if it's a smeared function, need a struct
798                useRes=1
799        endif
800        if(dimsize(resW,1) > 4)
801                isUSANS=1
802        endif
803       
804        // do not construct constraints for any of the coefficients that are being held
805        // -- this will generate an "unknown error" from the curve fitting
806        // -- if constraints are not used, the constr wave is killed (null), but that's OK
807        if(useConstr)
808                Make/O/T/N=0 constr
809                String constraintExpression
810                Variable i, nPnts=DimSize(lolim, 0),nextRow=0
811                for (i=0; i < nPnts; i += 1)
812                        if (strlen(lolim[i]) > 0 && hold[i] == 0)
813                                InsertPoints nextRow, 1, constr
814                                sprintf constraintExpression, "K%d > %s", i, lolim[i]
815                                constr[nextRow] = constraintExpression
816                                nextRow += 1
817                        endif
818                        if (strlen(hilim[i]) > 0 && hold[i] == 0)
819                                InsertPoints nextRow, 1, constr
820                                sprintf constraintExpression, "K%d < %s", i, hilim[i]
821                                constr[nextRow] = constraintExpression
822                                nextRow += 1
823                        endif
824                endfor
825        else
826                KillWaves/Z constr
827        endif
828
829        // 20JUN if useCursors is true, and there are no cursors on the specified data set, uncheck and set to false
830        // this is a last line of defense, and should never actually do anything...
831        if(useCursors)
832                useCursors = AreCursorsCorrect(folderStr)
833        endif
834        //if useCursors, and the data is USANS, need to recalculate the matrix if the range is new
835        Variable pt1,pt2,newN,mPt1,mPt2
836        String noteStr
837        if(useCursors && isUSANS )
838                //where are the cursors, and what is the status of the current matrix?
839                if(pcsr(A) > pcsr(B))
840                        pt1 = pcsr(B)
841                        pt2 = pcsr(A)
842                else
843                        pt1 = pcsr(A)
844                        pt2 = pcsr(B)
845                endif
846               
847                noteStr = note(resW)
848                mPt1 = NumberByKey("P1",noteStr,"=",";")
849                mPt2 = NumberByKey("P2",noteStr,"=",";")
850                if((mPt1 != pt1) || (mPt2 != pt2) )
851                        // need to recalculate
852                        USANS_RE_CalcWeights(folderStr,pt1,pt2)
853                        Print "Done recalculating the matrix"
854                endif
855               
856                Wave trimResW=$(DF+folderStr+"_res"+"t")        //put the trimmed resW in the struct for the fit!
857                Wave fs.resW=trimResW
858        endif
859        if(useCursors)
860                //find the points so that genetic optimization can use them
861                if(pcsr(A) > pcsr(B))
862                        pt1 = pcsr(B)
863                        pt2 = pcsr(A)
864                else
865                        pt1 = pcsr(A)
866                        pt2 = pcsr(B)
867                endif
868        else
869                //if cursors are not being used, find the first and last points of the data set, and pass them
870                pt1 = 0
871                pt2 = numpnts(yw)
872        endif
873               
874// create these variables so that FuncFit will set them on exit
875        Variable/G V_FitError=0                         //0=no err, 1=error,(2^1+2^0)=3=singular matrix
876        Variable/G V_FitQuitReason=0            //0=ok,1=maxiter,2=user stop,3=no chisq decrease
877
878        NVAR useGenCurveFit = root:Packages:NIST:gUseGenCurveFit
879// don't use the auto-destination with no flag, it doesn't appear to work correctly
880// dispatch the fit
881
882// currently, none of the fit functions are defined as threadsafe, so I don't think that the /NTHR flag really
883// does anything. The functions themselves can be threaded since they are AAO, and that is probably enough,
884// since it doesn't make much sense to thread threads. In addition, there is a little-publicized warning
885// in the WM help file that /C=texWave cannot be used to specify constraints for threadsafe functions!
886// The textwave would have to be parsed into a constraint matrix first, then passed as /C={cMat,cVec}.
887// -- just something to watch out for.
888
889// now two more flags... ,useResiduals,useTextBox
890        Variable tb = 1+2+4+8+16+256+512                //See CurveFit docs for bit settings for /TBOX flag
891
892        do
893                Variable t0 = stopMStimer(-2)           // corresponding print is at the end of the do-while loop (outside)
894
895
896                if(useGenCurveFit)
897               
898#if !(exists("GenCurveFit"))
899                        // XOP not available
900                        useGenCurveFit = 0
901                        Abort "Genetic Optimiztion XOP not available. Reverting to normal optimization."       
902#endif
903                        //send everything to a function, to reduce the clutter
904                        // useEps and useConstr are not needed
905                        // pass the structure to get the current waves, including the trimmed USANS matrix
906                        //
907                        // I don't know that GetCurveFit can do residuals, so I'm not passing that flag, or the text box flag
908                        //
909                        Variable chi,pt
910
911                        chi = DoGenCurveFit(useRes,useCursors,sw,fitYw,fs,funcStr,getHStr(hold),val,lolim,hilim,pt1,pt2)
912                        pt = val
913
914                        break
915                       
916                endif
917               
918                // now useCursors, useEps, and useConstr are all handled w/ /NWOK
919                // so there are only three conditions to test == 1 + 3 + 3 + 1 = 8 conditions
920               
921                if(useRes && useResiduals && useTextBox)                //do it all
922                        FuncFit/H=getHStr(hold) /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
923                        break
924                endif
925               
926                if(useRes && useResiduals)              //res + resid
927                        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 /R /NWOK
928                        break
929                endif
930
931               
932                if(useRes && useTextBox)                //res + text
933                        FuncFit/H=getHStr(hold) /NTHR=0 /TBOX=(tb) $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /STRC=fs /NWOK
934                        break
935                endif
936               
937                if(useRes)              //res only
938//                      Print "timing test for Cylinder_PolyRadius---"
939//                      Variable t0 = stopMStimer(-2)
940
941                        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
942                       
943//                      t0 = (stopMSTimer(-2) - t0)*1e-6
944//                      Printf  "CylPolyRad fit time using res and eps and /NTHR=0 time = %g seconds\r\r",t0
945//                      cw[0] = .01
946//                      cw[1] = 20
947//                      cw[2] = 400
948//                      cw[3] = 0.2
949//                      cw[4] = 3e-6
950//                      cw[5] = 0.0
951//                     
952//                      t0 = stopMSTimer(-2)
953//                      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
954//                      t0 = (stopMSTimer(-2) - t0)*1e-6
955//                      Printf  "CylPolyRad fit time using res and eps and NO THREADING time = %g seconds\r\r",t0
956                        break
957                endif
958                       
959               
960               
961/////   same as above, but all without useRes (no /STRC flag)
962                if(useResiduals && useTextBox)          //resid+ text
963                        FuncFit/H=getHStr(hold) /NTHR=0 /TBOX=(tb) $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /R /NWOK
964                        break
965                endif
966               
967                if(useResiduals)                //resid
968                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /R /NWOK
969                        break
970                endif
971
972               
973                if(useTextBox)          //text
974                        FuncFit/H=getHStr(hold) /NTHR=0 /TBOX=(tb) $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /NWOK
975                        break
976                endif
977               
978                //just a plain vanilla fit
979
980                FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /NWOK
981               
982        while(0)
983       
984        t0 = (stopMSTimer(-2) - t0)*1e-6
985        Printf  "fit time = %g seconds\r\r",t0
986       
987       
988        // append the fit
989        // need to manage duplicate copies
990        // Don't plot the full curve if cursors were used (set fitYw to NaN on entry...)
991        String traces=TraceNameList("", ";", 1 )                //"" as first parameter == look on the target graph
992        if(strsearch(traces,"FitYw",0) == -1)
993                if(useGenCurveFit && useCursors)
994                        WAVE trimX = trimX
995                        AppendtoGraph fitYw vs trimX
996                else
997                        AppendToGraph FitYw vs xw
998                endif
999        else
1000                RemoveFromGraph FitYw
1001                if(useGenCurveFit && useCursors)
1002                        WAVE trimX = trimX
1003                        AppendtoGraph fitYw vs trimX
1004                else
1005                        AppendToGraph FitYw vs xw
1006                endif
1007        endif
1008        ModifyGraph lsize(FitYw)=2,rgb(FitYw)=(0,0,0)
1009       
1010        DoUpdate                //force update of table and graph with fitted values (why doesn't this work? - the table still does not update)
1011       
1012        // report the results (to the panel?)
1013        if(useGenCurveFit)
1014                V_chisq = chi
1015                V_npnts = pt
1016        endif
1017        print "V_chisq = ",V_chisq
1018        print cw
1019        WAVE/Z w_sigma
1020        print w_sigma
1021        String resultStr=""
1022       
1023        if(waveexists(W_sigma))
1024                //append it to the table, if it's not already there
1025                CheckDisplayed/W=WrapperPanel#T0 W_sigma
1026                if(V_flag==0)
1027                        //not there, append it
1028                        AppendtoTable/W=wrapperPanel#T0 W_sigma
1029                else
1030                        //remove it, and put it back on to make sure it's the right one (do I need to do this?)
1031                        // -- not really, since any switch of the function menu takes W_Sigma off
1032                endif
1033        endif
1034       
1035        //now re-write the results
1036        sprintf resultStr,"Chi^2 = %g  Sqrt(X^2/N) = %g",V_chisq,sqrt(V_chisq/V_Npnts)
1037        resultStr = PadString(resultStr,63,0x20)
1038        GroupBox grpBox_2 title=resultStr
1039        ControlUpdate/W=WrapperPanel grpBox_2
1040        sprintf resultStr,"FitErr = %s : FitQuit = %s",W_ErrorMessage(V_FitError),W_QuitMessage(V_FitQuitReason)
1041        resultStr = PadString(resultStr,63,0x20)
1042        GroupBox grpBox_3 title=resultStr
1043        ControlUpdate/W=WrapperPanel grpBox_3
1044       
1045        Variable yesSave=0,yesReport=0
1046        ControlInfo/W=WrapperPanel check_4
1047        yesReport = V_Value
1048        ControlInfo/W=WrapperPanel check_5
1049        yesSave = V_Value
1050       
1051       
1052        if(yesReport)
1053                String parStr=GetWavesDataFolder(cw,1)+ WaveList("*param*"+suffix, "", "TEXT:1," )              // this is *hopefully* one wave
1054                String topGraph= WinName(0,1)   //this is the topmost graph
1055       
1056                DoUpdate                //force an update of the graph before making a copy of it for the report
1057
1058                //if GenCurveFit used, V_startRow and V_endRow may not exist - so read the cursors? but the cursors may not be used, so
1059                // there won't be anything on the graph...
1060                //
1061                W_GenerateReport(funcStr,folderStr,$parStr,cw,yesSave,V_chisq,W_sigma,V_npnts,V_FitError,V_FitQuitReason,V_startRow,V_endRow,topGraph)
1062        endif
1063       
1064        SetDataFolder root:
1065        return(0)
1066End
1067
1068// parse something off of a table, or ?
1069Function/S getHStr(hold)
1070        Wave hold
1071       
1072        String str=""
1073        Variable ii
1074        for(ii=0;ii<numpnts(hold);ii+=1)
1075                str += num2str(hold[ii])
1076        endfor
1077
1078//      print str
1079        if(strsearch(str, "1", 0) == -1)
1080                return ("")
1081        else
1082                return(str)
1083        endif
1084End
1085
1086//taken from SRK Auto_Fit, and modified to work better with FitWrapper
1087//must have AutoGraph as the name of the graph window (any size)
1088// func is the name of the function (for print only)
1089//par and coef are the exact names of the waves
1090//yesSave==1 will save the file(name=func+time)
1091//
1092Function W_GenerateReport(func,dataname,param,ans,yesSave,chiSq,sigWave,npts,fitErr,fitQuit,fitStart,fitEnd,topGraph)
1093        String func,dataname
1094        Wave/T param
1095        Wave ans
1096        Variable yesSave,chiSq
1097        Wave sigWave
1098        Variable npts,fitErr,fitQuit,fitStart,fitEnd
1099        String topGraph
1100       
1101        String str,pictStr="P_"
1102        String nb="Report"
1103               
1104        // bring report up
1105        DoWindow/F Report
1106        if (V_flag == 0)                // Report notebook doesn't exist ?
1107                NewNotebook/W=(10,45,550,620)/F=1/N=Report as "Report"
1108        endif
1109        // delete old stuff
1110        Notebook $nb selection={startOfFile, endOfFile}, text="\r", selection={startOfFile, startOfFile}
1111       
1112        //setup
1113        Notebook $nb defaultTab=36, statusWidth=252, pageMargins={72,72,72,72}
1114        Notebook $nb showRuler=1, rulerUnits=1, updating={1, 60}
1115        Notebook $nb newRuler=Normal, justification=0, margins={0,0,468}, spacing={0,0,0}, tabs={}, rulerDefaults={"Geneva",10,0,(0,0,0)}
1116//     
1117        // insert title
1118        Notebook $nb newRuler=Title, justification=1, rulerDefaults={"Times", 16, 1, (0, 0, 0)}
1119        sprintf str, "Fit to %s, %s, %s\r\r", func,Secs2Date(datetime, 0), time()
1120        Notebook $nb ruler=Title, text=str
1121       
1122        // insert fit results
1123        Variable num=numpnts(ans),ii=0
1124        Notebook $nb ruler=Normal
1125        Notebook $nb  margins={18,18,504}, tabs={63 + 3*8192}
1126        str = "Data file: " + dataname + "\r\r"
1127        Notebook $nb text=str
1128        Notebook $nb ruler=Normal
1129        Notebook $nb margins={18,18,504}, tabs={144,234,252}
1130        do
1131                sprintf str, "%s = \t%g\t±\t%g\r", param[ii],ans[ii],sigwave[ii]
1132                Notebook $nb text=str
1133                ii+=1
1134        while(ii<num)
1135       
1136        //
1137        // no "fitted range" for 2D data, so make sure that this exists before using it
1138        Wave/Z dataXw = $("root:"+dataname+":"+dataname+"_q")   
1139        //
1140        Notebook $nb ruler=Normal
1141        Notebook $nb  margins={18,18,504}, tabs={63+3*8192}, fStyle=1, textRGB=(65000,0,0)
1142       
1143        sprintf str,"chisq = %g\r",chisq
1144        Notebook $nb textRGB=(65000,0,0),fstyle=1,text=str
1145        sprintf str,"Npnts = %g \t\t Sqrt(X^2/N) = %g\r",npts,sqrt(chiSq/npts)
1146        Notebook $nb textRGB=(0,0,0),fstyle=0, text=str
1147        if(WaveExists(dataXw))
1148                sprintf str "Fitted range = [%d,%d] = %g < Q < %g\r",fitStart,fitEnd,dataXw(fitStart),dataXw(fitEnd)
1149                Notebook $nb textRGB=(0,0,0),fstyle=0, text=str
1150        endif
1151        sprintf str,"FitError = %s\t\tFitQuitReason = %s\r",W_ErrorMessage(FitErr),W_QuitMessage(FitQuit)
1152        Notebook $nb textRGB=(65000,0,0),fstyle=1,text=str
1153        Notebook $nb ruler=Normal
1154       
1155        // insert graphs
1156        if(WaveExists(dataXw))
1157                Notebook $nb picture={$topGraph(0, 0, 400, 300), -5, 1}, text="\r"
1158        //
1159        else            //must be 2D Gizmo
1160                Execute "ExportGizmo Clip"                      //this ALWAYS is a PICT or BMP. Gizmo windows are different...
1161                LoadPict/Q/O "Clipboard",tmp_Gizmo
1162                Notebook $nb picture={tmp_Gizmo(0, 0, 400, 300), 0, 1}, text="\r"
1163        endif
1164        //Notebook Report picture={Table1, 0, 0}, text="\r"
1165       
1166        // show the top of the report
1167        Notebook $nb  selection= {startOfFile, startOfFile},  findText={"", 1}
1168       
1169        //save the notebook and the graphic file
1170        if(yesSave)
1171                String nameStr=CleanupName(func,0)
1172                nameStr += "_"+dataname
1173                nameStr = ReplaceString("Smeared",nameStr,"Sm_")                //if Smeared function, shorten the name
1174                //make sure the name is no more than 31 characters
1175                namestr = namestr[0,30]         //if shorter than 31, this will NOT pad to 31 characters
1176                Print "file saved as ",nameStr
1177                SaveNotebook /O/P=home/S=2 $nb as nameStr
1178                //save the graph separately as a PICT file, 2x screen
1179                pictStr += nameStr
1180                pictStr = pictStr[0,28]         //need a shorter name - why?
1181//              DoWindow/F $topGraph
1182                // E=-5 is png @screen resolution
1183                // E=2 is PICT @2x screen resolution
1184///             SavePICT /E=-5/O/P=home /I/W=(0,0,3,3) as pictStr
1185                if(WaveExists(dataXw))
1186                        SavePICT /E=-5/O/P=home/WIN=$topGraph /W=(0,0,400,300) as pictStr
1187                else
1188                        Execute "ExportGizmo /P=home as \""+pictStr+"\""
1189                        //SavePICT /E=-5/O/P=home/WIN=$topGraph /W=(0,0,400,300) as pictStr
1190                endif
1191        Endif
1192       
1193        // ???maybe print the notebook too?
1194End
1195
1196Function/S W_ErrorMessage(code)
1197        Variable code
1198       
1199        switch (code)
1200                case 0:
1201                        return "No Error"
1202                        break
1203                case 3: //2^0 + 2^1
1204                        return "Singular Matrix"
1205                        break
1206                case 5:         //(2^0 + 2^2)
1207                        return "Out of Memory"
1208                        break
1209                case 9:         //(2^0 + 2^3)
1210                        return "Func= NaN or Inf"
1211                        break
1212                default:
1213                        return "Unknown error code "+num2str(code)
1214        endswitch
1215end
1216
1217Function/S W_QuitMessage(code)
1218        Variable code
1219       
1220        switch (code)
1221                case 0:
1222                        return "No Error"
1223                        break
1224                case 1:
1225                        return "Max iterations - re-run fit"
1226                        break
1227                case 2:
1228                        return "User terminated fit"
1229                        break
1230                case 3:
1231                        return "No decrease in chi-squared"
1232                        break
1233                default:
1234                        return "Unknown Quit code "+num2str(code)
1235        endswitch
1236end
1237
1238Function UseInfoTextBoxCheckProc(cba) : CheckBoxControl
1239        STRUCT WMCheckboxAction &cba
1240
1241        switch( cba.eventCode )
1242                case 2: // mouse up
1243                        Variable checked = cba.checked
1244                        if(checked)
1245                                //print "checked, use textBox in the next fit"
1246                        else
1247                                //print "unchecked, ask to remove TextBox from the graph"
1248                                ControlInfo/W=WrapperPanel popup_0
1249                                RemoveTextBox(S_value)
1250                        endif
1251                        break
1252        endswitch
1253
1254        return 0
1255End
1256
1257//does not report an error if the text box is not there
1258// -- so I'll just be lazy and not check to see if it's there
1259//
1260Function RemoveTextBox(folderStr)
1261        String folderStr
1262       
1263        DoAlert 1,"Remove the TextBox from the graph?"
1264        if(V_flag == 1)
1265                String str = "CF_"+folderStr+"_i"
1266                TextBox/K/N=$str
1267        endif
1268        return(0)
1269End
1270
1271Function UseResidualsCheckProc(cba) : CheckBoxControl
1272        STRUCT WMCheckboxAction &cba
1273
1274        switch( cba.eventCode )
1275                case 2: // mouse up
1276                        Variable checked = cba.checked
1277                        if(checked)
1278                                //print "checked, use them in the next fit"
1279                        else
1280                                //print "unchecked, ask to remove residuals from the graph"
1281                                ControlInfo/W=WrapperPanel popup_0
1282                                RemoveResiduals(S_value)
1283                        endif
1284                        break
1285        endswitch
1286
1287        return 0
1288End
1289
1290// the default name from the /R flag is "Res_" + yWaveName
1291//
1292// better to find the wave that starts with "Res_" and remove that one in case the
1293// wave names get too long
1294//
1295// the difficulty now is that the residual wave ends up in root: and not with the data....
1296// -- not really a problem, but adds to clutter
1297Function RemoveResiduals(folderStr)
1298        String folderStr
1299       
1300        String list="",topWin=""
1301        Variable num,ii
1302        String str
1303
1304        DoAlert 1,"Remove the residuals from the graph?"
1305        if(V_flag == 1)
1306//              String topGraph= WinName(0,1)   //this is the topmost graph
1307                list=TraceNameList("", ";", 1 )         //"" as first parameter == look on the target graph
1308                num=ItemsInList(list)
1309               
1310                for(ii=0;ii<num;ii+=1)
1311                        str = StringFromList(ii, list ,";")
1312                        if(strsearch(str, "Res_", 0) != -1)
1313                                RemoveFromGraph $str
1314                        endif
1315                endfor
1316       
1317                SetDataFolder root:
1318        endif
1319       
1320        return(0)
1321End
1322
1323Function Toggle2DControlsCheckProc(cba) : CheckBoxControl
1324        STRUCT WMCheckboxAction &cba
1325
1326        switch( cba.eventCode )
1327                case 2: // mouse up
1328                        Variable checked = cba.checked
1329                        if(checked)
1330                                //print "change the buttons to 2D"
1331                                Button button_0,proc=Do2DFitButtonProc,title="Do 2D Fit"
1332                                Button button_1,size={120,20},proc=Plot2DFunctionButtonProc,title="Plot 2D Function"
1333                                Button button_2,size={100,20},proc=Append2DModelButtonProc,title="Append 2D"
1334                                Button button_3,size={100,20},proc=Load2DDataButtonProc,title="Load 2D Data"
1335                               
1336                                Button button_2D_0,pos={550,60},size={70,20},proc=LogToggle2DButtonProc,title="Log/Lin"
1337                                Button button_2D_1,pos={520,37},size={100,20},proc=Plot2DButtonProc,title="Plot 2D Data"
1338                               
1339                                Button button_2D_0,disable=0            //visible again, and enabled
1340                                Button button_2D_1,disable=0
1341                        else
1342                                //print "unchecked, change them back to 1D"
1343                                Button button_0,pos={520,93},size={100,20},proc=DoTheFitButton,title="Do 1D Fit"
1344                                Button button_1,pos={280,57},size={120,20},proc=PlotModelFunction,title="Plot 1D Function"
1345                                Button button_2,pos={300,93},size={100,20},proc=AppendModelToTarget,title="Append 1D"
1346                                Button button_3,pos={300,20},size={100,20},proc=W_LoadDataButtonProc,title="Load 1D Data"
1347                               
1348                                Button button_2D_0,disable=3    //hide the extra 2D buttons, and disable
1349                                Button button_2D_1,disable=3
1350                        endif
1351                        break
1352        endswitch
1353
1354        return 0
1355End
1356
1357// function to either add or remove the cursors from the topmost graph, as needed
1358
1359Function UseCursorsWrapperProc(cba) : CheckBoxControl
1360        STRUCT WMCheckboxAction &cba
1361
1362
1363        switch( cba.eventCode )
1364                case 2: // mouse up
1365               
1366                        // check to make sure there really is a "topmost" graph         
1367                        String topGraph= WinName(0,1)   //this is the topmost graph
1368                        if(cmpstr(topGraph,"")==0)      //no graphs, uncheck and exit
1369                                CheckBox check_0,value=0
1370                                return(0)
1371                        endif
1372                               
1373                        String ciStr = CsrInfo(A , topGraph)
1374                       
1375                        ControlInfo/W=wrapperpanel popup_0
1376                        String folderStr=S_Value
1377                        String traceList = TraceNameList(topGraph, ";", 1 )             
1378               
1379                        Variable checked = cba.checked
1380                       
1381                        if(checked)
1382                                //print "add the cursors to the topmost graph, if the data set is there, or move them"
1383                                if(strlen(ciStr)==0 && strsearch(traceList, folderStr, 0) != -1 )               //no cursors && data is there
1384                                        ShowInfo
1385                                        Wave yw=$("root:"+folderStr+":"+folderStr+"_i")
1386                                        Cursor/P/W=$topGraph A, $(folderStr+"_i"),0
1387                                        Cursor/P/W=$topGraph/A=0 B, $(folderStr+"_i"),numpnts(yw)-1                     //deactivate the one at the high Q end
1388                                        DoUpdate
1389                                elseif (strlen(ciStr)!=0 && strsearch(traceList, folderStr, 0) != -1 ) //cursors present, but on wrong data
1390                                        Wave yw=$("root:"+folderStr+":"+folderStr+"_i")
1391                                        Cursor/P/W=$topGraph A, $(folderStr+"_i"),0                                                             //move the cursors
1392                                        Cursor/P/W=$topGraph/A=0 B, $(folderStr+"_i"),numpnts(yw)-1
1393                                        DoUpdate
1394                                endif
1395                               
1396                                AreCursorsCorrect(folderStr)
1397                        else
1398                                //print "unchecked, remove the cursors"
1399                                // go back to the full matrix for the resolution calculation (not if SANS data...)
1400                                if(waveExists($("root:"+folderStr+":weights_save")))
1401                                        Duplicate/O $("root:"+folderStr+":weights_save"), $("root:"+folderStr+":"+folderStr+"_res"),$("root:"+folderStr+":"+folderStr+"_rest")
1402                                endif
1403
1404                                HideInfo
1405                                Cursor/K A
1406                                Cursor/K B
1407                        endif
1408                        break
1409        endswitch
1410
1411        return 0
1412End
1413
1414// returns 1 if the specified data is on the top graph && has cursors on it
1415// returns 0 and unchecks the box if anything is wrong
1416//
1417// only call this function if the cursor box is checked, to uncheck it as needed
1418// if the box is unchecked, leave it be.
1419//
1420Function AreCursorsCorrect(folderStr)
1421        String folderStr
1422       
1423        String topGraph= WinName(0,1)   //this is the topmost graph
1424        if(cmpstr(topGraph,"")==0)      //no graphs, uncheck and exit
1425                CheckBox check_0,win=wrapperpanel,value=0
1426                return(0)
1427        endif
1428               
1429        String traceAisOn = CsrWave(A , "", 0)
1430        if(     strsearch(traceAisOn, folderStr, 0) == -1)              //data and cursors don't match
1431                CheckBox check_0,win=wrapperpanel,value=0
1432                HideInfo
1433                Cursor/K A
1434                Cursor/K B
1435                return(0)
1436        endif
1437       
1438        return(1)
1439End
Note: See TracBrowser for help on using the repository browser.