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

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

Made the preference panel fancier, with a tab control. this makes it much easier to add more things in the future. Added two more SANS items to turn off some detector corrections. good for testing, but maybe a bit dangerous.

removed the SANSPreferences procedure file from the general includes list for reduction. kept it in the very old versions of the includes (510 and older) for backwards comaptibility. new experiments start with 520 or higher.

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