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

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

Adding option to force use of Trapezoidal integration in USANS smearing for debug purposes.

Setting global variable root:NIST:Packages:USANSUseTrap = 1 will turn on the trapezoidal routine.

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