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

Last change on this file since 481 was 481, checked in by ajj, 14 years ago

Sundry changes...

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