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

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

Adding the model of a cylinder with spherical end caps. By taking all of the limiting cases, 5 models are added. Since the geometries are sufficiently different, I thought it best to add as separate models. Corresponding changes have been made to the Wrapper and the modelPicker

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