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

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

Closing RT ticket by using 76 point quadrature on MultiShell? model

Also has some minor changes to PlotManager? and Wrapper, intermediate changes as I'm working towards 2D fitting functions. Shouldn't break anything, but doesn't really add anything just yet.

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