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

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

Modified installer to copy folders, rather than move them. This allows the installer to be re-run without downloading or unzipping a fresh copy.

Added a "refresh" button to the PlotManager?. Streamlined the filtering out of non-plottable data.

Made XML the default (set the global to 1 in Wrapper, Initialize, and Main_USANS).

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