source: sans/Analysis/branches/ajj_23APR07/IGOR_Package_Files/Put in User Procedures/SANS_Models_v3.00/Packages/Wrapper.ipf @ 223

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

Globalfit now adds the correct graph to the report whether or not the progress graph is displayed.

Wrapper now has a button for feedback, position to be determined later.

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