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

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

some tweaks to the fit wrapper, starting to get plot and append functional

File size: 14.6 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//
11// if model is Smeared, search the DF for coefficients
12// if new DF chosen, need to reset
13// if new model function, need to reset table
14//
15// create hold_mod (0/1), constr_low_mod, constr_hi_mod
16// in either DF (smeared) or in root: (normal)
17// and put these in the table as needed
18//
19Window WrapperPanel() : Panel
20        PauseUpdate; Silent 1           // building window...
21        NewPanel /W=(459,44,1113,499)/N=wrapperPanel as "Curve Fit Setup"
22       
23        GroupBox grpBox_0,pos={18,11},size={350,113}
24        GroupBox grpBox_1,pos={386,10},size={247,113}
25        Button button_0,pos={523,93},size={100,20},proc=DoTheFitButton,title="Do The Fit"
26        Button button_1,pos={270,57},size={80,20},proc=PlotModelFunction,title="Plot"
27        Button button_2,pos={270,93},size={80,20},proc=AppendModelToTarget,title="Append"
28        PopupMenu popup_0,pos={30,21},size={218,20},title="Data Set"
29        PopupMenu popup_0,mode=1,value= #"DataSetPopupList()"
30        PopupMenu popup_1,pos={30,57},size={136,20},title="Function"
31        PopupMenu popup_1,mode=1,value= #"W_FunctionPopupList()"
32        PopupMenu popup_2,pos={30,93},size={123,20},title="Coefficients"
33        PopupMenu popup_2,mode=1,value= #"W_CoefPopupList()",proc=Coef_PopMenuProc
34        CheckBox check_0,pos={400,19},size={79,14},title="Use Cursors?",value= 0
35        CheckBox check_1,pos={400,42},size={74,14},title="Use Epsilon?",value= 0
36        CheckBox check_2,pos={400,65},size={95,14},title="Use Constraints?",value= 0
37        CheckBox check_3,pos={280,24},size={72,14},title="From target",value= 0
38        Edit/W=(20,174,634,435)/HOST=# 
39        ModifyTable width(Point)=0
40        RenameWindow #,T0
41        SetActiveSubwindow ##
42EndMacro
43
44
45// is there a simpler way to do this?
46Function/S DataSetPopupList()
47
48        String str=GetAList(4),tmp="",onTargetStr=""
49        Variable ii
50        ControlInfo check_3
51        if(V_Value==1)          //if "from target" checked
52                //ther must be a better way to do this
53                onTargetStr = TraceNameList("",";",1)
54                onTargetStr = ReplaceString("_i",onTargetStr,"")                //get rid of the "_i"
55                for(ii=0;ii<ItemsInList(onTargetStr);ii+=1)
56                        if(WhichListItem(StringFromList(ii,onTargetStr,";"), str  , ";") != -1)
57                                tmp = Addlistitem(StringFromList(ii,onTargetStr,";"),tmp)               //only keep the matches w/data folder listing
58                        endif
59                endfor
60                return(tmp)
61        endif
62
63        if(strlen(str)==0)
64                str = "No data loaded"
65        endif
66        str = SortList(str)
67       
68        return(str)
69End
70
71
72// show the available models
73// not the f*
74// not the *X XOPS
75//
76// KIND:10 should show only user-defined curve fitting functions
77// - not XOPs
78// - not other user-defined functions
79Function/S W_FunctionPopupList()
80        String list,tmp
81        list = FunctionList("*",";","KIND:10")          //get everything
82       
83        list = RemoveFromList("Sum_Model", list  ,";")
84       
85        tmp = FunctionList("*_proto",";","KIND:10")             //prototypes
86        list = RemoveFromList(tmp, list  ,";")
87
88        tmp = FunctionList("f*",";","KIND:10")          //point calculations
89        list = RemoveFromList(tmp, list  ,";")
90       
91        // this should be a null string with KIND:10
92        tmp = FunctionList("*X",";","KIND:10")          //XOPs, also point calculations
93        list = RemoveFromList(tmp, list  ,";")
94       
95        if(strlen(list)==0)
96                list = "No functions plotted"
97        endif
98       
99        list = SortList(list)
100        return(list)
101End
102
103// show all the appropriate coefficient waves
104//
105// also need to search the folder listed in "data set" popup
106// for smeared coefs
107//
108// - or - restrict the coefficient list based on the model function
109//
110Function/S W_CoefPopupList()
111        String list
112        setDataFolder root:
113        list = WaveList("coef*",";","")
114       
115        ControlInfo popup_0
116        if(V_Value != 0)                //0== no items in menu
117                if(DataFolderExists("root:"+S_Value))
118                        SetDataFolder $("root:"+S_Value)
119                        list += WaveList("*coef*",";","")
120                endif
121        endif
122       
123        if(strlen(list)==0)
124                list = "No functions plotted"
125        endif
126        list = SortList(list)
127       
128        setDataFolder root:
129        return(list)
130End
131
132// if the coefficients are changed, then update the table
133//
134//update the table
135// may be easier to just kill the subwindow (table) and create a new one
136// need to set/reset all of the waves in the table
137//
138// !! only respond to mouse up
139//
140Function Coef_PopMenuProc(pa) : PopupMenuControl
141        STRUCT WMPopupAction &pa
142
143        switch( pa.eventCode )
144                case 2: // mouse up
145                        Variable popNum = pa.popNum
146                        String popStr = pa.popStr
147                        String suffix = getModelSuffix(popStr)
148                        ControlInfo popup_0
149                        String folderStr=S_Value
150                       
151                        if(DataFolderExists("root:"+folderStr))
152                                SetDataFolder $("root:"+folderStr)
153                                if(!exists(popStr))
154                                        // must be unsmeared model, work in the root folder
155                                        SetDataFolder root:                             
156                                        if(!exists(popStr))             //this should be fine if the coef filter is working, but check anyhow
157                                                DoAlert 0,"the coefficient and data sets do not match"
158                                                return 0
159                                        endif
160                                endif
161                        else
162                                return(0)               //get out
163                        endif
164                       
165                        // farm the work out to another function?
166                        Variable num=numpnts($popStr)
167                        // make the necessary waves
168                        Make/O/D/N=(num) $("epsilon"+suffix),$("Hold"+suffix)
169                        Make/O/T/N=(num) $("LoLim"+suffix),$("HiLim"+suffix)
170                       
171                        // default epsilon values, sometimes needed for the fit
172                        Wave eps = $("epsilon"+suffix)
173                        Wave coef=$popStr
174                        eps = abs(coef*1e-4) + 1e-10                    //default eps is proportional to the coefficients
175                        WAVE/T LoLim = $("LoLim"+suffix)
176                        WAVE/T HiLim = $("HiLim"+suffix)
177                        LoLim = ""              //should have nicer way of keeping the previous values
178                        HiLim = ""
179                       
180                        // clear the table (a subwindow)
181                        KillWindow wrapperPanel#T0
182                        Edit/W=(20,174,634,435)/HOST=#
183                        RenameWindow #,T0
184                        // get them onto the table
185                        // how do I get the parameter name?
186                        String param = WaveList("*param*"+suffix, "", "TEXT:1," )               //this is *hopefully* one wave
187                        AppendtoTable/W=wrapperPanel#T0 $param,$(popStr)
188                        AppendToTable/W=wrapperPanel#T0 $("Hold"+suffix),$("LoLim"+suffix),$("HiLim"+suffix),$("epsilon"+suffix)
189                        ModifyTable width(Point)=0
190                       
191                        SetDataFolder root:
192                        break
193        endswitch
194
195        return 0
196End
197
198Function/S getModelSuffix(modelStr)
199        String modelStr
200       
201        Variable pos=Strsearch(modelStr,"_",Inf,1)              //look backwards to find "_"
202       
203        return(modelStr[pos,strlen(modelStr)-1])
204End
205
206// How to bypass the step of plot and append?
207//
208// - does not yet work
209// -- may need more serious changes in the way the "Plot" macros work
210// - may need to have a separate "append" button that looks at what is available in the specified
211//   data folder, or as a PauseForUser, after the plot is done
212//
213// - different Cmd if smeared or unsmeared
214// - stringent "PlotNNN" naming requirements
215// - how to kill the generated table and graph, that are not needed now
216//
217// - how to plot when there are no files loaded, no data folders, no resolution information
218//
219Function PlotModelFunction(ba) : ButtonControl
220        STRUCT WMButtonAction &ba
221
222        String folderStr,funcStr,coefStr,cmdStr=""
223        Variable useCursors,useEps,useConstr
224       
225        switch( ba.eventCode )
226                case 2: // mouse up
227                        ControlInfo popup_0
228                        folderStr=S_Value
229                       
230                        ControlInfo popup_1
231                        funcStr=S_Value
232                       
233                        // check for smeared or smeared function
234                        if(stringmatch(funcStr, "Smear*" )==1)
235                                //it's a smeared model
236                                sprintf cmdStr, "Plot%s(\"%s\")",funcStr,folderStr
237                        else
238                                // it's not,                   
239                                sprintf cmdStr, "Plot%s()",funcStr
240                        endif
241                       
242                        //Print cmdStr
243                        Execute cmdStr
244                        break
245        endswitch
246       
247        return 0
248End
249
250// How to bypass the step of plot and append?
251//
252// do it in two separate events
253//
254Function AppendModelToTarget(ba) : ButtonControl
255        STRUCT WMButtonAction &ba
256
257        String coefStr,suffix,yWStr,xWStr,folderStr
258       
259        switch( ba.eventCode )
260                case 2: // mouse up                     
261                        ControlInfo popup_2
262                        coefStr=S_Value
263                        suffix = getModelSuffix(coefStr)
264                       
265                        // check for smeared or smeared function
266                        if(stringmatch(coefStr, "smear*" )==1)
267                                //it's a smeared model
268                                ControlInfo popup_0
269                                folderStr=S_Value
270                                xWStr = "root:"+folderStr+":smeared_qvals"
271                                ywStr = "root:"+folderStr+":smeared"+suffix
272                        else
273                                // it's not, so it's in the root folder
274                                xWStr = "xwave"+suffix
275                                yWStr = "ywave"+suffix
276                        endif
277                       
278                        Wave yw = $yWStr
279                        Wave xw = $xWStr
280                        AppendtoGraph yw vs xw
281                        break
282        endswitch
283       
284        return 0
285End
286
287
288// this should parse the panel and call the FitWrapper() function
289Function DoTheFitButton(ba) : ButtonControl
290        STRUCT WMButtonAction &ba
291
292        String folderStr,funcStr,coefStr
293        Variable useCursors,useEps,useConstr
294       
295        switch( ba.eventCode )
296                case 2: // mouse up
297                        ControlInfo popup_0
298                        folderStr=S_Value
299                       
300                        ControlInfo popup_1
301                        funcStr=S_Value
302                       
303                        ControlInfo popup_2
304                        coefStr=S_Value
305                       
306                        Controlinfo check_0
307                        useCursors=V_Value
308                        Controlinfo check_1
309                        useEps=V_Value
310                        Controlinfo check_2
311                        useConstr=V_Value
312                       
313                        FitWrapper(folderStr,funcStr,coefStr,useCursors,useEps,useConstr)
314                       
315                        //      DoUpdate (does not work!)
316                        //?? why do I need to force an update ??
317                        if(!exists("root:"+folderStr+":"+coefStr))
318                                Wave w=$coefStr
319                        else
320                                Wave w=$("root:"+folderStr+":"+coefStr) //smeared coefs in data folder
321                        endif
322                        w[0] += 1e-6
323                        w[0] -= 1e-6
324       
325                        break
326        endswitch
327       
328        return 0
329End
330
331
332/////////////////////////////////
333
334// wrapper to do the desired fit
335//
336// folderStr is the data folder for the desired data set
337//
338// -- this looks like something that can be made rather generic rather easily
339//
340Function FitWrapper(folderStr,funcStr,coefStr,useCursors,useEps,useConstr)
341        String folderStr,funcStr,coefStr
342        Variable useCursors,useEps,useConstr
343
344        String suffix=getModelSuffix(coefStr)
345       
346        SetDataFolder $("root:"+folderStr)
347        if(!exists(coefStr))
348                // must be unsmeared model, work in the root folder
349                SetDataFolder root:                             
350                if(!exists(coefStr))            //this should be fine if the coef filter is working, but check anyhow
351                        DoAlert 0,"the coefficient and data sets do not match"
352                        return 0
353                endif
354        endif
355               
356        WAVE cw=$(coefStr)     
357        Wave hold=$("Hold"+suffix)
358        Wave/T lolim=$("LoLim"+suffix)
359        Wave/T hilim=$("HiLim"+suffix)
360        Wave eps=$("epsilon"+suffix)
361       
362// fill a struct instance whether I need one or not
363        String DF="root:"+folderStr+":"
364       
365        Struct ResSmearAAOStruct fs
366        WAVE resW = $(DF+folderStr+"_res")             
367        WAVE fs.resW =  resW
368        WAVE yw=$(DF+folderStr+"_i")
369        WAVE xw=$(DF+folderStr+"_q")
370        WAVE sw=$(DF+folderStr+"_s")
371        Wave fs.coefW = cw
372        Wave fs.yW = yw
373        Wave fs.xW = xw
374       
375        Duplicate/O yw $(DF+"FitYw")
376        WAVE fitYw = $(DF+"FitYw")
377        fitYw = NaN
378       
379        Variable useRes=0
380        if(stringmatch(funcStr, "Smear*"))              // if it's a smeared function, need a struct
381                useRes=1
382        endif
383       
384        Make/O/T/N=0 constr
385        if(useConstr)
386                String constraintExpression
387                Variable i, nPnts=DimSize(lolim, 0),nextRow=0
388                for (i=0; i < nPnts; i += 1)
389                        if (strlen(lolim[i]) > 0)
390                                InsertPoints nextRow, 1, constr
391                                sprintf constraintExpression, "K%d > %s", i, lolim[i]
392                                constr[nextRow] = constraintExpression
393                                nextRow += 1
394                        endif
395                        if (strlen(hilim[i]) > 0)
396                                InsertPoints nextRow, 1, constr
397                                sprintf constraintExpression, "K%d < %s", i, hilim[i]
398                                constr[nextRow] = constraintExpression
399                                nextRow += 1
400                        endif
401                endfor
402        endif
403
404        //if useCursors, and the data is USANS, need to feed a trimmed matrix to the fit
405        if(useCursors && (dimsize(resW,1) > 4) )
406                Variable pt1,pt2,newN
407                if(pcsr(A) > pcsr(B))
408                        pt1 = pcsr(B)
409                        pt2 = pcsr(A)
410                else
411                        pt1 = pcsr(A)
412                        pt2 = pcsr(B)
413                endif
414                newN = pt2 - pt1 + 1            // +1 includes both cursors in the fit
415                Make/O/D/N=(newN,newN) $(DF+"crsrResW")
416                WAVE crsrResW = $(DF+"crsrResW")
417                crsrResW = resW[p+pt1][q+pt1]
418                //assign to the struct
419                WAVE fs.resW =  crsrResW               
420        endif
421////
422
423//don't use the auto-destination with no flag, it doesn't appear to work correctly
424        do
425                if(useRes && useEps && useCursors && useConstr)         //do it all
426                        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
427                        break
428                endif
429               
430                if(useRes && useEps && useCursors)              //no constr
431                        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
432                        break
433                endif
434               
435                if(useRes && useEps && useConstr)               //no crsr
436                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /STRC=fs
437                        break
438                endif
439               
440                if(useRes && useCursors && useConstr)           //no eps
441                        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
442                        break
443                endif
444               
445                if(useRes && useCursors)                //no eps, no constr
446                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /D=fitYw /STRC=fs
447                        break
448                endif
449               
450                if(useRes && useEps)            //no crsr, no constr
451                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /STRC=fs
452                        break
453                endif
454       
455                if(useRes && useConstr)         //no crsr, no eps
456                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /C=constr /STRC=fs
457                        break
458                endif
459               
460                if(useRes)              //just res
461                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /STRC=fs
462                        break
463                endif
464               
465/////   same as above, but all without useRes
466                if(useEps && useCursors && useConstr)           //do it all
467                        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
468                        break
469                endif
470               
471                if(useEps && useCursors)                //no constr
472                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /E=eps /D=fitYw
473                        break
474                endif
475               
476                if(useEps && useConstr)         //no crsr
477                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr
478                        break
479                endif
480               
481                if(useCursors && useConstr)             //no eps
482                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /D=fitYw /C=constr
483                        break
484                endif
485               
486                if(useCursors)          //no eps, no constr
487                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /D=fitYw
488                        break
489                endif
490               
491                if(useEps)              //no crsr, no constr
492                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw
493                        break
494                endif
495       
496                if(useConstr)           //no crsr, no eps
497                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /C=constr
498                        break
499                endif
500               
501                //just a plain vanilla fit
502                FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw
503       
504        while(0)
505       
506        // append the fit
507        // need to manage duplicate copies
508        // Don't plot the full curve if cursors were used (set fitYw to NaN on entry...)
509        String traces=TraceNameList("", ";", 1 )
510        if(strsearch(traces,"FitYw",0) == -1)
511                AppendToGraph fitYw vs xw
512        endif
513       
514        DoUpdate                //force update of table and graph with fitted values (why doesn't this work? - the table still does not update)
515       
516        // report the results (to the panel?)
517        print "V_chisq = ",V_chisq
518        print cw
519        WAVE w_sigma
520        print w_sigma
521       
522        SetDataFolder root:
523        return(0)
524End
525
526// parse something off of a table, or ?
527Function/S getHStr(hold)
528        Wave hold
529       
530        String str=""
531        Variable ii
532        for(ii=0;ii<numpnts(hold);ii+=1)
533                str += num2str(hold[ii])
534        endfor
535
536//      print str
537        if(strsearch(str, "1", 0) == -1)
538                return ("")
539        else
540                return(str)
541        endif
542End
543
Note: See TracBrowser for help on using the repository browser.