source: sans/Dev/trunk/NCNR_User_Procedures/SANS/Analysis/Models/Packages/Wrapper_v40.ipf @ 397

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

Fixed bug in Wrapper whereby the table of coefficients would end up on the top graph rather than in the panel.

This seems to be triggered when a data set is loaded, followed by a non-smeared model, followed by a second data set.

Put in explicit references to the panel name and all seems well.

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