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

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

Minor bug fixes after testing the plot and append buttons on the WrapperPanel? for all of the (202) model functions. Changed how the parameter name wave is identified and added a special case for the SmearedRPAForm which has an extra parameter.

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