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

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

Lots of little changes:

changed debye function to a limiting value at low qRg to avoid numerical errors. There is no XOP, so no changes needed there.

Added MonteCarlo? simulation routine (1st draft) to the SANS Reduction, including changes to SASCALC to implement. Still very alpha with lots of bits to add. See the top of the monte carlo file for the list.

added MonteCarlo? file to SANS includes
added SAS folder to 2D display list to view MonteCarlo? results
removed more "non-functions" from the function popup in analysis. these were a result of motofit/genFit, and simultaneous loading of SANS/USANS reduction. More will follow.

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