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

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

Several disjoint changes:

1) Threaded the 1D Cylinder_PolyRadius function
2) in Wrapper, popping the data set list now will auto-pop the function, then the coef to properly update the table of coefficients.
3) tick units in the plots are suppressed (y-axis)
4) Killing data (PlotManager?) now kills the dependent variable so that the rest can be killed
5) Ellipsoid_2D function now has the correct notation of the rotation axis in the parameter names.

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