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

Last change on this file since 544 was 544, checked in by srkline, 14 years ago

Lots of changes to add the first version of a USANS simulator, like SASCALC

(!) first issue is with the entanglement of dependencies - need to load SANS macros first!

otherwise, worth a first test for interface and accuracy. behavior is similar to the 1D SASCALC

File size: 39.2 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=4.00
3#pragma IgorVersion=6.0
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        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.