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

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

Changed 2D model calculations to use a FIXED 25 integration points in an effort to get the number of integration points out of the fitting coefficient wave.

Added "Freeze Model" back to the SANS Models menu

Added the 2D model functions to the list on the model picker

Minor tweaks to the wrapper

File size: 29.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"
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
361// always pass this the coefficient string
362//
363// either "coef_"
364// or "smear_coef_"
365//
366Function/S getFunctionCoef(funcStr)
367        String funcStr
368
369        SVAR listStr=root:coefKWStr
370        String coefStr = StringByKey(funcStr, listStr  ,"=",";",0)
371
372        return(coefStr)
373End
374
375// always pass this the coefficient string
376//
377// either "coef_"
378// or "smear_coef_"
379//
380// does NOT return the leading "_" as part of the suffix
381Function/S getModelSuffix(coefStr)
382        String coefStr
383
384        SVAR listStr=root:suffixKWStr
385        String suffixStr = StringByKey(coefStr, listStr  ,"=",";",0)
386
387        return(suffixStr)
388//      Variable pos,start=0
389
390//      if(stringmatch(coefStr,"smear_*") == 1)
391//              start=7 //look forwards to find "_", skipping "smear_coe" if necessary
392//      endif
393//      pos=Strsearch(coefStr,"_",start,0)
394        //Print start, pos
395//      return(coefStr[pos,strlen(coefStr)-1])
396End
397
398
399
400// - this is based on stringent "PlotNNN" naming requirements
401//
402//  ???
403// - how to kill the generated table and graph, that are not needed now
404//
405Function PlotModelFunction(ba) : ButtonControl
406        STRUCT WMButtonAction &ba
407
408        String folderStr,funcStr,coefStr,cmdStr=""
409        Variable useCursors,useEps,useConstr
410       
411        Variable killWhat=0             //kill nothing as default
412       
413        switch( ba.eventCode )
414                case 2: // mouse up
415                        ControlInfo/W=WrapperPanel popup_0
416                        folderStr=S_Value
417                       
418                        ControlInfo/W=WrapperPanel popup_1
419                        funcStr=S_Value
420                       
421                        // check for smeared or smeared function
422                        if(stringmatch(funcStr, "Smear*" )==1)
423                                //it's a smeared model
424                                // check for the special case of RPA that has an extra parameter
425                                if(strsearch(funcStr, "RPAForm", 0 ,0) == -1)
426                                        sprintf cmdStr, "Plot%s(\"%s\")",funcStr,folderStr              //not RPA
427                                else
428                                        sprintf cmdStr, "Plot%s(\"%s\",)",funcStr,folderStr             //yes RPA, leave a comma for input
429                                endif
430                                killWhat = 1
431                        else
432                                // it's not,    don't kill the graph, just the table           
433                                sprintf cmdStr, "Plot%s()",funcStr
434                                killWhat = 2
435                        endif
436                       
437                        //Print cmdStr
438                        Execute cmdStr
439                       
440                        //pop the function menu to set the proper coefficients
441                        DoWindow/F WrapperPanel
442                        STRUCT WMPopupAction pa
443                        pa.popStr = funcStr
444                        pa.eventcode = 2
445                        Function_PopMenuProc(pa)
446       
447                        KillTopGraphAndTable(killWhat)          // crude
448       
449                        break
450        endswitch
451       
452        return 0
453End
454
455// passing 0 kills nothing
456// passing 1 kills the top graph and table
457// passing 2 kills the top table only
458//
459Function KillTopGraphAndTable(killwhat)
460        Variable killWhat
461       
462        String topGraph= WinName(0,1)   //this is the topmost graph     
463        String topTable= WinName(0,2)   //this is the topmost table
464
465        if(killWhat == 0)
466                return(0)
467        endif
468       
469        if(killWhat == 1)
470                KillWindow $topGraph
471                KillWindow $topTable
472        endif
473       
474        if(killWhat == 2)
475                KillWindow $topTable
476        endif
477       
478        return(0)
479End
480
481// How to bypass the step of plot and append?
482//
483// do it in two separate events
484//
485Function AppendModelToTarget(ba) : ButtonControl
486        STRUCT WMButtonAction &ba
487
488        String coefStr,suffix,yWStr,xWStr,folderStr
489       
490        switch( ba.eventCode )
491                case 2: // mouse up                     
492                        ControlInfo/W=WrapperPanel popup_2
493                        coefStr=S_Value
494                        suffix = getModelSuffix(coefStr)
495                       
496                        // check for smeared or smeared function
497                        if(stringmatch(coefStr, "smear*" )==1)
498                                //it's a smeared model
499                                ControlInfo/W=WrapperPanel popup_0
500                                folderStr=S_Value
501                                xWStr = "root:"+folderStr+":smeared_qvals"
502                                ywStr = "root:"+folderStr+":smeared_"+suffix
503                        else
504                                // it's not, so it's in the root folder
505                                xWStr = "xwave_"+suffix
506                                yWStr = "ywave_"+suffix
507                        endif
508                       
509                        Wave/Z yw = $yWStr
510                        Wave/Z xw = $xWStr
511                        if(WaveExists(yw) && WaveExists(xw))
512                                AppendtoGraph yw vs xw
513                        else
514                                DoAlert 0,"The selected model has not been plotted for the selected data set."
515                        endif
516                        break
517        endswitch
518       
519        return 0
520End
521
522
523// this should parse the panel and call the FitWrapper() function
524Function DoTheFitButton(ba) : ButtonControl
525        STRUCT WMButtonAction &ba
526
527        String folderStr,funcStr,coefStr
528        Variable useCursors,useEps,useConstr
529       
530        switch( ba.eventCode )
531                case 2: // mouse up
532                        ControlInfo/W=WrapperPanel popup_0
533                        folderStr=S_Value
534                       
535                        ControlInfo/W=WrapperPanel popup_1
536                        funcStr=S_Value
537                       
538                        ControlInfo/W=WrapperPanel popup_2
539                        coefStr=S_Value
540                       
541                        ControlInfo/W=WrapperPanel check_0
542                        useCursors=V_Value
543                        ControlInfo/W=WrapperPanel check_1
544                        useEps=V_Value
545                        ControlInfo/W=WrapperPanel check_2
546                        useConstr=V_Value
547                       
548                        if(!CheckFunctionAndCoef(funcStr,coefStr))
549                                DoAlert 0,"The coefficients and function type do not match. Please correct the selections in the popup menus."
550                                break
551                        endif
552                       
553                        FitWrapper(folderStr,funcStr,coefStr,useCursors,useEps,useConstr)
554                       
555                        //      DoUpdate (does not work!)
556                        //?? why do I need to force an update ??
557                        if(!exists("root:"+folderStr+":"+coefStr))
558                                Wave w=$coefStr
559                        else
560                                Wave w=$("root:"+folderStr+":"+coefStr) //smeared coefs in data folder
561                        endif
562                        w[0] += 1e-6
563                        w[0] -= 1e-6
564       
565                        break
566        endswitch
567       
568        return 0
569End
570
571Function CheckFunctionAndCoef(funcStr,coefStr)
572        String funcStr,coefStr
573       
574        SVAR listStr=root:coefKWStr
575        String properCoefStr = StringByKey(funcStr, listStr  ,"=",";",0)
576        if(cmpstr(coefStr,properCoefStr)==0)
577                return(1)               //true, the coef is the correct match
578        endif
579        return(0)                       //false, wrong coef
580End
581
582/////////////////////////////////
583
584// wrapper to do the desired fit
585//
586// folderStr is the data folder for the desired data set
587//
588//
589Function FitWrapper(folderStr,funcStr,coefStr,useCursors,useEps,useConstr)
590        String folderStr,funcStr,coefStr
591        Variable useCursors,useEps,useConstr
592
593        String suffix=getModelSuffix(coefStr)
594       
595        SetDataFolder $("root:"+folderStr)
596        if(!exists(coefStr))
597                // must be unsmeared model, work in the root folder
598                SetDataFolder root:                             
599                if(!exists(coefStr))            //this should be fine if the coef filter is working, but check anyhow
600                        DoAlert 0,"the coefficient and data sets do not match"
601                        return 0
602                endif
603        endif
604               
605        WAVE cw=$(coefStr)     
606        Wave hold=$("Hold_"+suffix)
607        Wave/T lolim=$("LoLim_"+suffix)
608        Wave/T hilim=$("HiLim_"+suffix)
609        Wave eps=$("epsilon_"+suffix)
610       
611// fill a struct instance whether I need one or not
612        String DF="root:"+folderStr+":"
613       
614        Struct ResSmearAAOStruct fs
615        WAVE resW = $(DF+folderStr+"_res")             
616        WAVE fs.resW =  resW
617        WAVE yw=$(DF+folderStr+"_i")
618        WAVE xw=$(DF+folderStr+"_q")
619        WAVE sw=$(DF+folderStr+"_s")
620        Wave fs.coefW = cw
621        Wave fs.yW = yw
622        Wave fs.xW = xw
623       
624        Duplicate/O yw $(DF+"FitYw")
625        WAVE fitYw = $(DF+"FitYw")
626        fitYw = NaN
627       
628        Variable useRes=0
629        if(stringmatch(funcStr, "Smear*"))              // if it's a smeared function, need a struct
630                useRes=1
631        endif
632       
633        // do not construct constraints for any of the coefficients that are being held
634        // -- this will generate an "unknown error" from the curve fitting
635        Make/O/T/N=0 constr
636        if(useConstr)
637                String constraintExpression
638                Variable i, nPnts=DimSize(lolim, 0),nextRow=0
639                for (i=0; i < nPnts; i += 1)
640                        if (strlen(lolim[i]) > 0 && hold[i] == 0)
641                                InsertPoints nextRow, 1, constr
642                                sprintf constraintExpression, "K%d > %s", i, lolim[i]
643                                constr[nextRow] = constraintExpression
644                                nextRow += 1
645                        endif
646                        if (strlen(hilim[i]) > 0 && hold[i] == 0)
647                                InsertPoints nextRow, 1, constr
648                                sprintf constraintExpression, "K%d < %s", i, hilim[i]
649                                constr[nextRow] = constraintExpression
650                                nextRow += 1
651                        endif
652                endfor
653        endif
654
655        //if useCursors, and the data is USANS, need to feed a (reassigned) trimmed matrix to the fit
656        Variable pt1,pt2,newN
657        if(useCursors && (dimsize(resW,1) > 4) )
658                if(pcsr(A) > pcsr(B))
659                        pt1 = pcsr(B)
660                        pt2 = pcsr(A)
661                else
662                        pt1 = pcsr(A)
663                        pt2 = pcsr(B)
664                endif
665                newN = pt2 - pt1 + 1            // +1 includes both cursors in the fit
666                Make/O/D/N=(newN,newN) $(DF+"crsrResW")
667                WAVE crsrResW = $(DF+"crsrResW")
668                crsrResW = resW[p+pt1][q+pt1]
669                //assign to the struct
670                WAVE fs.resW =  crsrResW               
671        endif
672
673// create these variables so that FuncFit will set them on exit
674        Variable/G V_FitError=0                         //0=no err, 1=error,(2^1+2^0)=3=singular matrix
675        Variable/G V_FitQuitReason=0            //0=ok,1=maxiter,2=user stop,3=no chisq decrease
676       
677// don't use the auto-destination with no flag, it doesn't appear to work correctly
678// dispatch the fit
679        do
680                if(useRes && useEps && useCursors && useConstr)         //do it all
681                        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
682                        break
683                endif
684               
685                if(useRes && useEps && useCursors)              //no constr
686                        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
687                        break
688                endif
689               
690                if(useRes && useEps && useConstr)               //no crsr
691                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /STRC=fs
692                        break
693                endif
694               
695                if(useRes && useCursors && useConstr)           //no eps
696                        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
697                        break
698                endif
699               
700                if(useRes && useCursors)                //no eps, no constr
701                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /D=fitYw /STRC=fs
702                        break
703                endif
704               
705                if(useRes && useEps)            //no crsr, no constr
706//                      Print "timing test for Cylinder_PolyRadius --- the supposedly threaded version ---"
707//                      Variable t0 = stopMStimer(-2)
708                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /STRC=fs
709//                      t0 = (stopMSTimer(-2) - t0)*1e-6
710//                      Printf  "CylPolyRad fit time using res and eps and /NTHR=0 time = %g seconds\r\r",t0
711                       
712//                      cw[0] = .01
713//                      cw[1] = 20
714//                      cw[2] = 400
715//                      cw[3] = 0.2
716//                      cw[4] = 3e-6
717//                      cw[5] = 0.0
718//                     
719//                      t0 = stopMSTimer(-2)
720//                      FuncFit/H=getHStr(hold) $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /STRC=fs
721//                      t0 = (stopMSTimer(-2) - t0)*1e-6
722//                      Printf  "CylPolyRad fit time using res and eps and NO THREADING time = %g seconds\r\r",t0
723                        break
724                endif
725       
726                if(useRes && useConstr)         //no crsr, no eps
727                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /C=constr /STRC=fs
728                        break
729                endif
730               
731                if(useRes)              //just res
732                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /STRC=fs
733                        break
734                endif
735               
736/////   same as above, but all without useRes (no /STRC flag)
737                if(useEps && useCursors && useConstr)           //do it all
738                        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
739                        break
740                endif
741               
742                if(useEps && useCursors)                //no constr
743                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /E=eps /D=fitYw
744                        break
745                endif
746               
747                if(useEps && useConstr)         //no crsr
748                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr
749                        break
750                endif
751               
752                if(useCursors && useConstr)             //no eps
753                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /D=fitYw /C=constr
754                        break
755                endif
756               
757                if(useCursors)          //no eps, no constr
758                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /D=fitYw
759                        break
760                endif
761               
762                if(useEps)              //no crsr, no constr
763                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw
764                        break
765                endif
766       
767                if(useConstr)           //no crsr, no eps
768                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /C=constr
769                        break
770                endif
771               
772                //just a plain vanilla fit
773                FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw
774       
775        while(0)
776       
777        // append the fit
778        // need to manage duplicate copies
779        // Don't plot the full curve if cursors were used (set fitYw to NaN on entry...)
780        String traces=TraceNameList("", ";", 1 )                //"" as first parameter == look on the target graph
781        if(strsearch(traces,"FitYw",0) == -1)
782                AppendToGraph FitYw vs xw
783        else
784                RemoveFromGraph FitYw
785                AppendToGraph FitYw vs xw
786        endif
787        ModifyGraph lsize(FitYw)=2,rgb(FitYw)=(0,0,0)
788       
789        DoUpdate                //force update of table and graph with fitted values (why doesn't this work? - the table still does not update)
790       
791        // report the results (to the panel?)
792        print "V_chisq = ",V_chisq
793        print cw
794        WAVE w_sigma
795        print w_sigma
796        String resultStr=""
797               
798        //now re-write the results
799        sprintf resultStr,"Chi^2 = %g  Sqrt(X^2/N) = %g",V_chisq,sqrt(V_chisq/V_Npnts)
800        resultStr = PadString(resultStr,63,0x20)
801        GroupBox grpBox_2 title=resultStr
802        ControlUpdate/W=WrapperPanel grpBox_2
803        sprintf resultStr,"FitErr = %s : FitQuit = %s",W_ErrorMessage(V_FitError),W_QuitMessage(V_FitQuitReason)
804        resultStr = PadString(resultStr,63,0x20)
805        GroupBox grpBox_3 title=resultStr
806        ControlUpdate/W=WrapperPanel grpBox_3
807       
808        Variable yesSave=0,yesReport=0
809        ControlInfo/W=WrapperPanel check_4
810        yesReport = V_Value
811        ControlInfo/W=WrapperPanel check_5
812        yesSave = V_Value
813       
814       
815        if(yesReport)
816                String parStr=GetWavesDataFolder(cw,1)+ WaveList("*param*"+suffix, "", "TEXT:1," )              //this is *hopefully* one wave
817                String topGraph= WinName(0,1)   //this is the topmost graph
818       
819                DoUpdate                //force an update of the graph before making a copy of it for the report
820
821                W_GenerateReport(funcStr,folderStr,$parStr,cw,yesSave,V_chisq,W_sigma,V_npnts,V_FitError,V_FitQuitReason,V_startRow,V_endRow,topGraph)
822        endif
823       
824        SetDataFolder root:
825        return(0)
826End
827
828// parse something off of a table, or ?
829Function/S getHStr(hold)
830        Wave hold
831       
832        String str=""
833        Variable ii
834        for(ii=0;ii<numpnts(hold);ii+=1)
835                str += num2str(hold[ii])
836        endfor
837
838//      print str
839        if(strsearch(str, "1", 0) == -1)
840                return ("")
841        else
842                return(str)
843        endif
844End
845
846//taken from SRK Auto_Fit, and modified to work better with FitWrapper
847//must have AutoGraph as the name of the graph window (any size)
848// func is the name of the function (for print only)
849//par and coef are the exact names of the waves
850//yesSave==1 will save the file(name=func+time)
851//
852Function W_GenerateReport(func,dataname,param,ans,yesSave,chiSq,sigWave,npts,fitErr,fitQuit,fitStart,fitEnd,topGraph)
853        String func,dataname
854        Wave/T param
855        Wave ans
856        Variable yesSave,chiSq
857        Wave sigWave
858        Variable npts,fitErr,fitQuit,fitStart,fitEnd
859        String topGraph
860       
861        String str,pictStr="P_"
862        String nb="Report"
863               
864        // bring report up
865        DoWindow/F Report
866        if (V_flag == 0)                // Report notebook doesn't exist ?
867                NewNotebook/W=(10,45,550,620)/F=1/N=Report as "Report"
868        endif
869        // delete old stuff
870        Notebook $nb selection={startOfFile, endOfFile}, text="\r", selection={startOfFile, startOfFile}
871       
872        //setup
873        Notebook $nb defaultTab=36, statusWidth=252, pageMargins={72,72,72,72}
874        Notebook $nb showRuler=1, rulerUnits=1, updating={1, 60}
875        Notebook $nb newRuler=Normal, justification=0, margins={0,0,468}, spacing={0,0,0}, tabs={}, rulerDefaults={"Geneva",10,0,(0,0,0)}
876//     
877        // insert title
878        Notebook $nb newRuler=Title, justification=1, rulerDefaults={"Times", 16, 1, (0, 0, 0)}
879        sprintf str, "Fit to %s, %s, %s\r\r", func,Secs2Date(datetime, 0), time()
880        Notebook $nb ruler=Title, text=str
881       
882        // insert fit results
883        Variable num=numpnts(ans),ii=0
884        Notebook $nb ruler=Normal
885        Notebook $nb  margins={18,18,504}, tabs={63 + 3*8192}
886        str = "Data file: " + dataname + "\r\r"
887        Notebook $nb text=str
888        Notebook $nb ruler=Normal
889        Notebook $nb margins={18,18,504}, tabs={144,234,252}
890        do
891                sprintf str, "%s = \t%g\t±\t%g\r", param[ii],ans[ii],sigwave[ii]
892                Notebook $nb text=str
893                ii+=1
894        while(ii<num)
895       
896        //
897        // no "fitted range" for 2D data, so make sure that this exists before using it
898        Wave/Z dataXw = $("root:"+dataname+":"+dataname+"_q")   
899        //
900        Notebook $nb ruler=Normal
901        Notebook $nb  margins={18,18,504}, tabs={63+3*8192}, fStyle=1, textRGB=(65000,0,0)
902       
903        sprintf str,"chisq = %g\r",chisq
904        Notebook $nb textRGB=(65000,0,0),fstyle=1,text=str
905        sprintf str,"Npnts = %g \t\t Sqrt(X^2/N) = %g\r",npts,sqrt(chiSq/npts)
906        Notebook $nb textRGB=(0,0,0),fstyle=0, text=str
907        if(WaveExists(dataXw))
908                sprintf str "Fitted range = [%d,%d] = %g < Q < %g\r",fitStart,fitEnd,dataXw(fitStart),dataXw(fitEnd)
909                Notebook $nb textRGB=(0,0,0),fstyle=0, text=str
910        endif
911        sprintf str,"FitError = %s\t\tFitQuitReason = %s\r",W_ErrorMessage(FitErr),W_QuitMessage(FitQuit)
912        Notebook $nb textRGB=(65000,0,0),fstyle=1,text=str
913        Notebook $nb ruler=Normal
914       
915        // insert graphs
916        if(WaveExists(dataXw))
917                Notebook $nb picture={$topGraph(0, 0, 400, 300), 0, 1}, text="\r"
918        //
919        else            //must be 2D Gizmo
920                Execute "ExportGizmo Clip"
921                LoadPict/Q/O "Clipboard",tmp_Gizmo
922                Notebook $nb picture={tmp_Gizmo(0, 0, 400, 300), 0, 1}, text="\r"
923        endif
924        //Notebook Report picture={Table1, 0, 0}, text="\r"
925       
926        // show the top of the report
927        Notebook $nb  selection= {startOfFile, startOfFile},  findText={"", 1}
928       
929        //save the notebook and the graphic file
930        if(yesSave)
931                String nameStr=CleanupName(func,0)
932                nameStr = nameStr[0,8]  //shorten the name
933                nameStr += "_"+dataname
934                //make sure the name is no more than 31 characters
935                namestr = namestr[0,30]         //if shorter than 31, this will NOT pad to 31 characters
936                Print "file saved as ",nameStr
937                SaveNotebook /O/P=home/S=2 $nb as nameStr
938                //save the graph separately as a PICT file, 2x screen
939                pictStr += nameStr
940                pictStr = pictStr[0,28]         //need a shorter name - why?
941//              DoWindow/F $topGraph
942                // E=-5 is png @screen resolution
943                // E=2 is PICT @2x screen resolution
944///             SavePICT /E=-5/O/P=home /I/W=(0,0,3,3) as pictStr
945                if(WaveExists(dataXw))
946                        SavePICT /E=-5/O/P=home/WIN=$topGraph /W=(0,0,400,300) as pictStr
947                else
948                        Execute "ExportGizmo /P=home as \""+pictStr+"\""
949                        //SavePICT /E=-5/O/P=home/WIN=$topGraph /W=(0,0,400,300) as pictStr
950                endif
951        Endif
952       
953        // ???maybe print the notebook too?
954End
955
956Function/S W_ErrorMessage(code)
957        Variable code
958       
959        switch (code)
960                case 0:
961                        return "No Error"
962                        break
963                case 3: //2^0 + 2^1
964                        return "Singular Matrix"
965                        break
966                case 5:         //(2^0 + 2^2)
967                        return "Out of Memory"
968                        break
969                case 9:         //(2^0 + 2^3)
970                        return "Func= NaN or Inf"
971                        break
972                default:
973                        return "Unknown error code "+num2str(code)
974        endswitch
975end
976
977Function/S W_QuitMessage(code)
978        Variable code
979       
980        switch (code)
981                case 0:
982                        return "No Error"
983                        break
984                case 1:
985                        return "Max iterations - re-run fit"
986                        break
987                case 2:
988                        return "User terminated fit"
989                        break
990                case 3:
991                        return "No decrease in chi-squared"
992                        break
993                default:
994                        return "Unknown Quit code "+num2str(code)
995        endswitch
996end
997
998Function Toggle2DControlsCheckProc(cba) : CheckBoxControl
999        STRUCT WMCheckboxAction &cba
1000
1001        switch( cba.eventCode )
1002                case 2: // mouse up
1003                        Variable checked = cba.checked
1004                        if(checked)
1005                                //print "change the buttons to 2D"
1006                                Button button_0,proc=Do2DFitButtonProc,title="Do 2D Fit"
1007                                Button button_1,size={120,20},proc=Plot2DFunctionButtonProc,title="Plot 2D Function"
1008                                Button button_2,size={100,20},proc=Append2DModelButtonProc,title="Append 2D"
1009                                Button button_3,size={100,20},proc=Load2DDataButtonProc,title="Load 2D Data"
1010                               
1011                                Button button_2D_0,pos={550,60},size={70,20},proc=LogToggle2DButtonProc,title="Log/Lin"
1012                                Button button_2D_1,pos={520,37},size={100,20},proc=Plot2DButtonProc,title="Plot 2D Data"
1013                               
1014                                Button button_2D_0,disable=0            //visible again, and enabled
1015                                Button button_2D_1,disable=0
1016                        else
1017                                //print "unchecked, change them back to 1D"
1018                                Button button_0,pos={520,93},size={100,20},proc=DoTheFitButton,title="Do 1D Fit"
1019                                Button button_1,pos={280,57},size={120,20},proc=PlotModelFunction,title="Plot 1D Function"
1020                                Button button_2,pos={300,93},size={100,20},proc=AppendModelToTarget,title="Append 1D"
1021                                Button button_3,pos={300,20},size={100,20},proc=W_LoadDataButtonProc,title="Load 1D Data"
1022                               
1023                                Button button_2D_0,disable=3    //hide the extra 2D buttons, and disable
1024                                Button button_2D_1,disable=3
1025                        endif
1026                        break
1027        endswitch
1028
1029        return 0
1030End
Note: See TracBrowser for help on using the repository browser.