source: sans/Analysis/branches/ajj_23APR07/IGOR_Package_Files/Put in User Procedures/SANS_Models_v4.00/Packages/Wrapper_v40.ipf @ 292

Last change on this file since 292 was 292, checked in by srkline, 15 years ago

Changed the behavior of the useCursors checkbox to now automaticaly place cursors at the ends of the data set, if the selected data set is on the top graph. unchecking the box removes all cursors from the graph.

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