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

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

bug fixes related to XML changes in the file loader in PlotUtilsMacro?

bug fix in Wrapper, in the error checking of coefficient wave names

File size: 36.3 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("",properCoefStr)==0)
680                return(0)               //false, no match found, so properCoefStr is returned null
681        endif
682        if(cmpstr(coefStr,properCoefStr)==0)
683                return(1)               //true, the coef is the correct match
684        endif
685        return(0)                       //false, wrong coef
686End
687
688/////////////////////////////////
689
690// wrapper to do the desired fit
691//
692// folderStr is the data folder for the desired data set
693//
694//
695Function FitWrapper(folderStr,funcStr,coefStr,useCursors,useEps,useConstr)
696        String folderStr,funcStr,coefStr
697        Variable useCursors,useEps,useConstr
698
699        String suffix=getModelSuffix(coefStr)
700       
701        SetDataFolder $("root:"+folderStr)
702        if(!exists(coefStr))
703                // must be unsmeared model, work in the root folder
704                SetDataFolder root:                             
705                if(!exists(coefStr))            //this should be fine if the coef filter is working, but check anyhow
706                        DoAlert 0,"the coefficient and data sets do not match"
707                        return 0
708                endif
709        endif
710               
711        WAVE cw=$(coefStr)     
712        Wave hold=$("Hold_"+suffix)
713        Wave/T lolim=$("LoLim_"+suffix)
714        Wave/T hilim=$("HiLim_"+suffix)
715        Wave eps=$("epsilon_"+suffix)
716       
717// fill a struct instance whether I need one or not
718        String DF="root:"+folderStr+":"
719       
720        Struct ResSmearAAOStruct fs
721        WAVE/Z resW = $(DF+folderStr+"_res")                    //these may not exist, if 3-column data is used
722        WAVE/Z fs.resW =  resW
723        WAVE yw=$(DF+folderStr+"_i")
724        WAVE xw=$(DF+folderStr+"_q")
725        WAVE sw=$(DF+folderStr+"_s")
726        Wave fs.coefW = cw
727        Wave fs.yW = yw
728        Wave fs.xW = xw
729       
730        Duplicate/O yw $(DF+"FitYw")
731        WAVE fitYw = $(DF+"FitYw")
732        fitYw = NaN
733       
734        Variable useRes=0
735        if(stringmatch(funcStr, "Smear*"))              // if it's a smeared function, need a struct
736                useRes=1
737        endif
738       
739        // do not construct constraints for any of the coefficients that are being held
740        // -- this will generate an "unknown error" from the curve fitting
741        Make/O/T/N=0 constr
742        if(useConstr)
743                String constraintExpression
744                Variable i, nPnts=DimSize(lolim, 0),nextRow=0
745                for (i=0; i < nPnts; i += 1)
746                        if (strlen(lolim[i]) > 0 && hold[i] == 0)
747                                InsertPoints nextRow, 1, constr
748                                sprintf constraintExpression, "K%d > %s", i, lolim[i]
749                                constr[nextRow] = constraintExpression
750                                nextRow += 1
751                        endif
752                        if (strlen(hilim[i]) > 0 && hold[i] == 0)
753                                InsertPoints nextRow, 1, constr
754                                sprintf constraintExpression, "K%d < %s", i, hilim[i]
755                                constr[nextRow] = constraintExpression
756                                nextRow += 1
757                        endif
758                endfor
759        endif
760
761        // 20JUN if useCursors is true, and there are no cursors on the specified data set, uncheck and set to false
762        // this is a last line of defense, and should never actually do anything...
763        if(useCursors)
764                useCursors = AreCursorsCorrect(folderStr)
765        endif
766        //if useCursors, and the data is USANS, need to recalculate the matrix if the range is new
767        Variable pt1,pt2,newN,mPt1,mPt2
768        String noteStr
769        if(useCursors && (dimsize(resW,1) > 4) )
770                //where are the cursors, and what is the status of the current matrix?
771                if(pcsr(A) > pcsr(B))
772                        pt1 = pcsr(B)
773                        pt2 = pcsr(A)
774                else
775                        pt1 = pcsr(A)
776                        pt2 = pcsr(B)
777                endif
778               
779                noteStr = note(resW)
780                mPt1 = NumberByKey("P1",noteStr,"=",";")
781                mPt2 = NumberByKey("P2",noteStr,"=",";")
782                if((mPt1 != pt1) || (mPt2 != pt2) )
783                        // need to recalculate
784                        USANS_RE_CalcWeights(folderStr,pt1,pt2)
785                        Print "Done recalculating the matrix"
786                endif
787               
788                Wave trimResW=$(DF+folderStr+"_res"+"t")        //put the trimmed resW in the struct for the fit!
789                Wave fs.resW=trimResW
790
791        endif
792               
793// create these variables so that FuncFit will set them on exit
794        Variable/G V_FitError=0                         //0=no err, 1=error,(2^1+2^0)=3=singular matrix
795        Variable/G V_FitQuitReason=0            //0=ok,1=maxiter,2=user stop,3=no chisq decrease
796       
797// don't use the auto-destination with no flag, it doesn't appear to work correctly
798// dispatch the fit
799        do
800//              Variable t0 = stopMStimer(-2)           // corresponding print is at the end of the do-while loop (outside)
801               
802                if(useRes && useEps && useCursors && useConstr)         //do it all
803                        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
804                        break
805                endif
806               
807                if(useRes && useEps && useCursors)              //no constr
808                        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
809                        break
810                endif
811               
812                if(useRes && useEps && useConstr)               //no crsr
813                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /STRC=fs
814                        break
815                endif
816               
817                if(useRes && useCursors && useConstr)           //no eps
818                        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
819                        break
820                endif
821               
822                if(useRes && useCursors)                //no eps, no constr
823                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /D=fitYw /STRC=fs
824                        break
825                endif
826               
827                if(useRes && useEps)            //no crsr, no constr
828//                      Print "timing test for Cylinder_PolyRadius --- the supposedly threaded version ---"
829//                      Variable t0 = stopMStimer(-2)
830                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /STRC=fs
831//                      t0 = (stopMSTimer(-2) - t0)*1e-6
832//                      Printf  "CylPolyRad fit time using res and eps and /NTHR=0 time = %g seconds\r\r",t0
833                       
834//                      cw[0] = .01
835//                      cw[1] = 20
836//                      cw[2] = 400
837//                      cw[3] = 0.2
838//                      cw[4] = 3e-6
839//                      cw[5] = 0.0
840//                     
841//                      t0 = stopMSTimer(-2)
842//                      FuncFit/H=getHStr(hold) $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /STRC=fs
843//                      t0 = (stopMSTimer(-2) - t0)*1e-6
844//                      Printf  "CylPolyRad fit time using res and eps and NO THREADING time = %g seconds\r\r",t0
845                        break
846                endif
847       
848                if(useRes && useConstr)         //no crsr, no eps
849                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /C=constr /STRC=fs
850                        break
851                endif
852               
853                if(useRes)              //just res
854                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /STRC=fs
855                        break
856                endif
857               
858/////   same as above, but all without useRes (no /STRC flag)
859                if(useEps && useCursors && useConstr)           //do it all
860                        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
861                        break
862                endif
863               
864                if(useEps && useCursors)                //no constr
865                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /E=eps /D=fitYw
866                        break
867                endif
868               
869                if(useEps && useConstr)         //no crsr
870                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr
871                        break
872                endif
873               
874                if(useCursors && useConstr)             //no eps
875                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /D=fitYw /C=constr
876                        break
877                endif
878               
879                if(useCursors)          //no eps, no constr
880                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /D=fitYw
881                        break
882                endif
883               
884                if(useEps)              //no crsr, no constr
885                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw
886                        break
887                endif
888       
889                if(useConstr)           //no crsr, no eps
890                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /C=constr
891                        break
892                endif
893               
894                //just a plain vanilla fit
895                FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw
896       
897        while(0)
898       
899//      t0 = (stopMSTimer(-2) - t0)*1e-6
900//      Printf  "fit time = %g seconds\r\r",t0
901       
902        // append the fit
903        // need to manage duplicate copies
904        // Don't plot the full curve if cursors were used (set fitYw to NaN on entry...)
905        String traces=TraceNameList("", ";", 1 )                //"" as first parameter == look on the target graph
906        if(strsearch(traces,"FitYw",0) == -1)
907                AppendToGraph FitYw vs xw
908        else
909                RemoveFromGraph FitYw
910                AppendToGraph FitYw vs xw
911        endif
912        ModifyGraph lsize(FitYw)=2,rgb(FitYw)=(0,0,0)
913       
914        DoUpdate                //force update of table and graph with fitted values (why doesn't this work? - the table still does not update)
915       
916        // report the results (to the panel?)
917        print "V_chisq = ",V_chisq
918        print cw
919        WAVE/Z w_sigma
920        print w_sigma
921        String resultStr=""
922               
923        //now re-write the results
924        sprintf resultStr,"Chi^2 = %g  Sqrt(X^2/N) = %g",V_chisq,sqrt(V_chisq/V_Npnts)
925        resultStr = PadString(resultStr,63,0x20)
926        GroupBox grpBox_2 title=resultStr
927        ControlUpdate/W=WrapperPanel grpBox_2
928        sprintf resultStr,"FitErr = %s : FitQuit = %s",W_ErrorMessage(V_FitError),W_QuitMessage(V_FitQuitReason)
929        resultStr = PadString(resultStr,63,0x20)
930        GroupBox grpBox_3 title=resultStr
931        ControlUpdate/W=WrapperPanel grpBox_3
932       
933        Variable yesSave=0,yesReport=0
934        ControlInfo/W=WrapperPanel check_4
935        yesReport = V_Value
936        ControlInfo/W=WrapperPanel check_5
937        yesSave = V_Value
938       
939       
940        if(yesReport)
941                String parStr=GetWavesDataFolder(cw,1)+ WaveList("*param*"+suffix, "", "TEXT:1," )              //this is *hopefully* one wave
942                String topGraph= WinName(0,1)   //this is the topmost graph
943       
944                DoUpdate                //force an update of the graph before making a copy of it for the report
945
946                W_GenerateReport(funcStr,folderStr,$parStr,cw,yesSave,V_chisq,W_sigma,V_npnts,V_FitError,V_FitQuitReason,V_startRow,V_endRow,topGraph)
947        endif
948       
949        SetDataFolder root:
950        return(0)
951End
952
953// parse something off of a table, or ?
954Function/S getHStr(hold)
955        Wave hold
956       
957        String str=""
958        Variable ii
959        for(ii=0;ii<numpnts(hold);ii+=1)
960                str += num2str(hold[ii])
961        endfor
962
963//      print str
964        if(strsearch(str, "1", 0) == -1)
965                return ("")
966        else
967                return(str)
968        endif
969End
970
971//taken from SRK Auto_Fit, and modified to work better with FitWrapper
972//must have AutoGraph as the name of the graph window (any size)
973// func is the name of the function (for print only)
974//par and coef are the exact names of the waves
975//yesSave==1 will save the file(name=func+time)
976//
977Function W_GenerateReport(func,dataname,param,ans,yesSave,chiSq,sigWave,npts,fitErr,fitQuit,fitStart,fitEnd,topGraph)
978        String func,dataname
979        Wave/T param
980        Wave ans
981        Variable yesSave,chiSq
982        Wave sigWave
983        Variable npts,fitErr,fitQuit,fitStart,fitEnd
984        String topGraph
985       
986        String str,pictStr="P_"
987        String nb="Report"
988               
989        // bring report up
990        DoWindow/F Report
991        if (V_flag == 0)                // Report notebook doesn't exist ?
992                NewNotebook/W=(10,45,550,620)/F=1/N=Report as "Report"
993        endif
994        // delete old stuff
995        Notebook $nb selection={startOfFile, endOfFile}, text="\r", selection={startOfFile, startOfFile}
996       
997        //setup
998        Notebook $nb defaultTab=36, statusWidth=252, pageMargins={72,72,72,72}
999        Notebook $nb showRuler=1, rulerUnits=1, updating={1, 60}
1000        Notebook $nb newRuler=Normal, justification=0, margins={0,0,468}, spacing={0,0,0}, tabs={}, rulerDefaults={"Geneva",10,0,(0,0,0)}
1001//     
1002        // insert title
1003        Notebook $nb newRuler=Title, justification=1, rulerDefaults={"Times", 16, 1, (0, 0, 0)}
1004        sprintf str, "Fit to %s, %s, %s\r\r", func,Secs2Date(datetime, 0), time()
1005        Notebook $nb ruler=Title, text=str
1006       
1007        // insert fit results
1008        Variable num=numpnts(ans),ii=0
1009        Notebook $nb ruler=Normal
1010        Notebook $nb  margins={18,18,504}, tabs={63 + 3*8192}
1011        str = "Data file: " + dataname + "\r\r"
1012        Notebook $nb text=str
1013        Notebook $nb ruler=Normal
1014        Notebook $nb margins={18,18,504}, tabs={144,234,252}
1015        do
1016                sprintf str, "%s = \t%g\t±\t%g\r", param[ii],ans[ii],sigwave[ii]
1017                Notebook $nb text=str
1018                ii+=1
1019        while(ii<num)
1020       
1021        //
1022        // no "fitted range" for 2D data, so make sure that this exists before using it
1023        Wave/Z dataXw = $("root:"+dataname+":"+dataname+"_q")   
1024        //
1025        Notebook $nb ruler=Normal
1026        Notebook $nb  margins={18,18,504}, tabs={63+3*8192}, fStyle=1, textRGB=(65000,0,0)
1027       
1028        sprintf str,"chisq = %g\r",chisq
1029        Notebook $nb textRGB=(65000,0,0),fstyle=1,text=str
1030        sprintf str,"Npnts = %g \t\t Sqrt(X^2/N) = %g\r",npts,sqrt(chiSq/npts)
1031        Notebook $nb textRGB=(0,0,0),fstyle=0, text=str
1032        if(WaveExists(dataXw))
1033                sprintf str "Fitted range = [%d,%d] = %g < Q < %g\r",fitStart,fitEnd,dataXw(fitStart),dataXw(fitEnd)
1034                Notebook $nb textRGB=(0,0,0),fstyle=0, text=str
1035        endif
1036        sprintf str,"FitError = %s\t\tFitQuitReason = %s\r",W_ErrorMessage(FitErr),W_QuitMessage(FitQuit)
1037        Notebook $nb textRGB=(65000,0,0),fstyle=1,text=str
1038        Notebook $nb ruler=Normal
1039       
1040        // insert graphs
1041        if(WaveExists(dataXw))
1042                Notebook $nb picture={$topGraph(0, 0, 400, 300), -5, 1}, text="\r"
1043        //
1044        else            //must be 2D Gizmo
1045                Execute "ExportGizmo Clip"                      //this ALWAYS is a PICT or BMP. Gizmo windows are different...
1046                LoadPict/Q/O "Clipboard",tmp_Gizmo
1047                Notebook $nb picture={tmp_Gizmo(0, 0, 400, 300), 0, 1}, text="\r"
1048        endif
1049        //Notebook Report picture={Table1, 0, 0}, text="\r"
1050       
1051        // show the top of the report
1052        Notebook $nb  selection= {startOfFile, startOfFile},  findText={"", 1}
1053       
1054        //save the notebook and the graphic file
1055        if(yesSave)
1056                String nameStr=CleanupName(func,0)
1057                nameStr = nameStr[0,8]  //shorten the name
1058                nameStr += "_"+dataname
1059                //make sure the name is no more than 31 characters
1060                namestr = namestr[0,30]         //if shorter than 31, this will NOT pad to 31 characters
1061                Print "file saved as ",nameStr
1062                SaveNotebook /O/P=home/S=2 $nb as nameStr
1063                //save the graph separately as a PICT file, 2x screen
1064                pictStr += nameStr
1065                pictStr = pictStr[0,28]         //need a shorter name - why?
1066//              DoWindow/F $topGraph
1067                // E=-5 is png @screen resolution
1068                // E=2 is PICT @2x screen resolution
1069///             SavePICT /E=-5/O/P=home /I/W=(0,0,3,3) as pictStr
1070                if(WaveExists(dataXw))
1071                        SavePICT /E=-5/O/P=home/WIN=$topGraph /W=(0,0,400,300) as pictStr
1072                else
1073                        Execute "ExportGizmo /P=home as \""+pictStr+"\""
1074                        //SavePICT /E=-5/O/P=home/WIN=$topGraph /W=(0,0,400,300) as pictStr
1075                endif
1076        Endif
1077       
1078        // ???maybe print the notebook too?
1079End
1080
1081Function/S W_ErrorMessage(code)
1082        Variable code
1083       
1084        switch (code)
1085                case 0:
1086                        return "No Error"
1087                        break
1088                case 3: //2^0 + 2^1
1089                        return "Singular Matrix"
1090                        break
1091                case 5:         //(2^0 + 2^2)
1092                        return "Out of Memory"
1093                        break
1094                case 9:         //(2^0 + 2^3)
1095                        return "Func= NaN or Inf"
1096                        break
1097                default:
1098                        return "Unknown error code "+num2str(code)
1099        endswitch
1100end
1101
1102Function/S W_QuitMessage(code)
1103        Variable code
1104       
1105        switch (code)
1106                case 0:
1107                        return "No Error"
1108                        break
1109                case 1:
1110                        return "Max iterations - re-run fit"
1111                        break
1112                case 2:
1113                        return "User terminated fit"
1114                        break
1115                case 3:
1116                        return "No decrease in chi-squared"
1117                        break
1118                default:
1119                        return "Unknown Quit code "+num2str(code)
1120        endswitch
1121end
1122
1123Function Toggle2DControlsCheckProc(cba) : CheckBoxControl
1124        STRUCT WMCheckboxAction &cba
1125
1126        switch( cba.eventCode )
1127                case 2: // mouse up
1128                        Variable checked = cba.checked
1129                        if(checked)
1130                                //print "change the buttons to 2D"
1131                                Button button_0,proc=Do2DFitButtonProc,title="Do 2D Fit"
1132                                Button button_1,size={120,20},proc=Plot2DFunctionButtonProc,title="Plot 2D Function"
1133                                Button button_2,size={100,20},proc=Append2DModelButtonProc,title="Append 2D"
1134                                Button button_3,size={100,20},proc=Load2DDataButtonProc,title="Load 2D Data"
1135                               
1136                                Button button_2D_0,pos={550,60},size={70,20},proc=LogToggle2DButtonProc,title="Log/Lin"
1137                                Button button_2D_1,pos={520,37},size={100,20},proc=Plot2DButtonProc,title="Plot 2D Data"
1138                               
1139                                Button button_2D_0,disable=0            //visible again, and enabled
1140                                Button button_2D_1,disable=0
1141                        else
1142                                //print "unchecked, change them back to 1D"
1143                                Button button_0,pos={520,93},size={100,20},proc=DoTheFitButton,title="Do 1D Fit"
1144                                Button button_1,pos={280,57},size={120,20},proc=PlotModelFunction,title="Plot 1D Function"
1145                                Button button_2,pos={300,93},size={100,20},proc=AppendModelToTarget,title="Append 1D"
1146                                Button button_3,pos={300,20},size={100,20},proc=W_LoadDataButtonProc,title="Load 1D Data"
1147                               
1148                                Button button_2D_0,disable=3    //hide the extra 2D buttons, and disable
1149                                Button button_2D_1,disable=3
1150                        endif
1151                        break
1152        endswitch
1153
1154        return 0
1155End
1156
1157// function to either add or remove the cursors from the topmost graph, as needed
1158
1159Function UseCursorsWrapperProc(cba) : CheckBoxControl
1160        STRUCT WMCheckboxAction &cba
1161
1162
1163        switch( cba.eventCode )
1164                case 2: // mouse up
1165               
1166                        // check to make sure there really is a "topmost" graph         
1167                        String topGraph= WinName(0,1)   //this is the topmost graph
1168                        if(cmpstr(topGraph,"")==0)      //no graphs, uncheck and exit
1169                                CheckBox check_0,value=0
1170                                return(0)
1171                        endif
1172                               
1173                        String ciStr = CsrInfo(A , topGraph)
1174                       
1175                        ControlInfo/W=wrapperpanel popup_0
1176                        String folderStr=S_Value
1177                        String traceList = TraceNameList(topGraph, ";", 1 )             
1178               
1179                        Variable checked = cba.checked
1180                       
1181                        if(checked)
1182                                //print "add the cursors to the topmost graph, if the data set is there, or move them"
1183                                if(strlen(ciStr)==0 && strsearch(traceList, folderStr, 0) != -1 )               //no cursors && data is there
1184                                        ShowInfo
1185                                        Wave yw=$("root:"+folderStr+":"+folderStr+"_i")
1186                                        Cursor/P/W=$topGraph A, $(folderStr+"_i"),0
1187                                        Cursor/P/W=$topGraph/A=0 B, $(folderStr+"_i"),numpnts(yw)-1                     //deactivate the one at the high Q end
1188                                        DoUpdate
1189                                elseif (strlen(ciStr)!=0 && strsearch(traceList, folderStr, 0) != -1 ) //cursors present, but on wrong data
1190                                        Wave yw=$("root:"+folderStr+":"+folderStr+"_i")
1191                                        Cursor/P/W=$topGraph A, $(folderStr+"_i"),0                                                             //move the cursors
1192                                        Cursor/P/W=$topGraph/A=0 B, $(folderStr+"_i"),numpnts(yw)-1
1193                                        DoUpdate
1194                                endif
1195                               
1196                                AreCursorsCorrect(folderStr)
1197                        else
1198                                //print "unchecked, remove the cursors"
1199                                // go back to the full matrix for the resolution calculation (not if SANS data...)
1200                                if(waveExists($("root:"+folderStr+":weights_save")))
1201                                        Duplicate/O $("root:"+folderStr+":weights_save"), $("root:"+folderStr+":"+folderStr+"_res"),$("root:"+folderStr+":"+folderStr+"_rest")
1202                                endif
1203
1204                                HideInfo
1205                                Cursor/K A
1206                                Cursor/K B
1207                        endif
1208                        break
1209        endswitch
1210
1211        return 0
1212End
1213
1214// returns 1 if the specified data is on the top graph && has cursors on it
1215// returns 0 and unchecks the box if anything is wrong
1216//
1217// only call this function if the cursor box is checked, to uncheck it as needed
1218// if the box is unchecked, leave it be.
1219//
1220Function AreCursorsCorrect(folderStr)
1221        String folderStr
1222       
1223        String topGraph= WinName(0,1)   //this is the topmost graph
1224        if(cmpstr(topGraph,"")==0)      //no graphs, uncheck and exit
1225                CheckBox check_0,win=wrapperpanel,value=0
1226                return(0)
1227        endif
1228               
1229        String traceAisOn = CsrWave(A , "", 0)
1230        if(     strsearch(traceAisOn, folderStr, 0) == -1)              //data and cursors don't match
1231                CheckBox check_0,win=wrapperpanel,value=0
1232                HideInfo
1233                Cursor/K A
1234                Cursor/K B
1235                return(0)
1236        endif
1237       
1238        return(1)
1239End
Note: See TracBrowser for help on using the repository browser.