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

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

Changed Plot* and PlotSmeared?* naming schemes to be all consistent prefixes for the actual function name, so that the macros can be constructed from the function name, or vice versa.

also some tweaks to the wrapper to make sure that plot and append really work

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