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

Last change on this file since 665 was 665, checked in by srkline, 13 years ago

Made preferences a common panel (moved to PlotUtilsMacro?.ipf and globals to root:Packages:NIST:) and added menu items for all packages. Many files had to be modified so that the preferences could be properly accessed

File Open dialog now is set to "All files" so that XML can be selected. I think that all open access that doesn't already have the full path go through this common function.

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