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

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

Simple change in all of the model function files to include the name of the parameter wave in the Keyword=list that is generated when a model is plotted. This is becoming an issue where the proper parameter wave can't be deduced from just the suffix, then there is nothing to put in the table.

I should have added this when I initially wrote the wrapper...

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