source: sans/Dev/trunk/NCNR_User_Procedures/Analysis/Packages/SumModel/SumSANSModels_v40.ipf @ 570

Last change on this file since 570 was 570, checked in by srkline, 13 years ago

Change (1):
In preparation for release, updated pragma IgorVersion?=6.1 in all procedures

Change (2):
As a side benefit of requiring 6.1, we can use the MultiThread? keyword to thread any model function we like. The speed benefit is only noticeable on functions that require at least one integration and at least 100 points (resolution smearing is NOT threaded, too many threadSafe issues, too little benefit). I have chosen to use the MultiThread? only on the XOP assignment. In the Igor code there are too many functions that are not explicitly declared threadsafe, making for a mess.

File size: 13.5 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma IgorVersion=6.1
3
4///////////////////////////////
5//
6//      17 DEC 04 SRK
7//
8// SumSANSModels.ipf
9//
10//      Procedures to sum two SANS model into a function that can
11// be used to fit SANS data sets. does this by soliciting input
12// from the user through a panel. Needs the function names, the
13// names of the coefficients, and the number of parameters
14// (same information for each model)
15//
16//      Then the "Plot" button on the panel creates the function
17// based on the panel selections. The model is named "Sum_Model",
18// the coef/params are "coef_sum" and "parameters_sum", respectively
19//
20//      The two original coef/param waves are tacked together. No attempt
21// is made to remove duplicate parameters. This is up to the user
22// to keep appropriate values fixed. (especially background)
23//
24//      Changing the popup values will not immediately change the output
25// function. The model must be re-plotted to "pick up" these new
26// selections.
27//
28// JUL 2007
29// - data folder aware
30// - AAO, structure aware
31// (smeared fitting still broken)
32// - created data folders are now buried in myGlobals
33// DEC 07
34// - created data folders are now :Packages:NIST:SumModel
35//
36///////////////////////////////
37
38//create the panel as needed
39//
40Proc Init_SumModelPanel()
41        DoWindow/F Sum_Model_Panel
42        if(V_flag==0)
43                if(!DataFolderExists("root:Packages:NIST"))
44                        NewDataFolder root:Packages:NIST
45                endif
46                NewDataFolder/O root:Packages:NIST:SumModel
47                InitSMPGlobals()
48                Sum_Model_Panel()
49        endif
50end
51
52// create the globals that the panel needs
53//
54Function InitSMPGlobals()
55        Variable/G root:Packages:NIST:SumModel:gNParMod1=0
56        Variable/G root:Packages:NIST:SumModel:gNParMod2=0
57end
58
59Window Sum_Model_Panel() : Panel
60        PauseUpdate; Silent 1           // building window...
61        NewPanel /W=(670,75,900,450)/K=1
62        DoWindow/C Sum_Model_Panel
63        SetDrawLayer UserBack
64        SetDrawEnv fstyle= 1
65        DrawText 14,17,"Sum Two Model Functions"
66        PopupMenu popup1_0,pos={15,69},size={131,20},title="Model"
67        PopupMenu popup1_0,mode=1,popvalue="Pick model 1",value= #"SumModelPopupList()"
68        PopupMenu popup2_0,pos={15,190},size={131,20},title="Model"
69        PopupMenu popup2_0,mode=1,popvalue="Pick model 2",value= #"SumModelPopupList()"
70        PopupMenu popup1_1,pos={15,98},size={173,20},title="Coef"
71        PopupMenu popup1_1,mode=1,popvalue="Pick coef for model 1",value= #"CoefPopupList()",proc=Func_1_2PopMenuProc
72        PopupMenu popup2_1,pos={15,221},size={173,20},title="Coef"
73        PopupMenu popup2_1,mode=1,popvalue="Pick coef for model 2",value= #"CoefPopupList()",proc=Func_1_2PopMenuProc
74        GroupBox group1,pos={5,50},size={216,107},title="Function # 1"
75        SetVariable setvar1,pos={14,128},size={140,15},title="# of Parameters"
76        SetVariable setvar1,limits={0,20,1},value= root:Packages:NIST:SumModel:gNParMod1
77        GroupBox group2,pos={5,171},size={216,107},title="Function # 2"
78        SetVariable setvar2,pos={14,249},size={140,15},title="# of Parameters"
79        SetVariable setvar2,limits={0,20,1},value= root:Packages:NIST:SumModel:gNParMod2
80        Button button0,pos={36,299},size={150,20},proc=PlotSumButtonProc,title="Plot Summed Model"
81        Button button1,pos={15,330},size={190,20},proc=PlotSmearedSumButtonProc,title="Plot Smeared Summed Model"
82        Button button2,pos={190,23},size={25,20},proc=Sum_HelpButtonProc,title="?"
83EndMacro
84
85Function Func_1_2PopMenuProc(pa) : PopupMenuControl
86        STRUCT WMPopupAction &pa
87
88        switch( pa.eventCode )
89                case 2: // mouse up
90                        Variable popNum = pa.popNum
91                        String popStr = pa.popStr
92                        String name=pa.ctrlName
93                        Variable num=0
94                       
95                        Wave/Z coef=$("root:"+popStr)
96                        if(WaveExists(coef))
97                                num=numpnts(coef)
98                        endif
99                       
100                       
101                        if(cmpstr(name,"popup1_1")==0)          //function #1
102                                NVAR pts1 = root:Packages:NIST:SumModel:gNParMod1
103                                pts1 = num
104                        else
105                                NVAR pts2 = root:Packages:NIST:SumModel:gNParMod2
106                                pts2 = num
107                        endif
108                       
109                        break
110        endswitch
111
112        return 0
113End
114
115// show the available models
116// but not the smeared versions
117// not the f*
118// not the *X XOPS
119//
120// KIND:10 should show only user-defined curve fitting functions
121// - not XOPs
122// - not other user-defined functions
123Function/S SumModelPopupList()
124        String list,tmp
125        list = FunctionList("!Smear*",";","KIND:10")            //don't show smeared models
126       
127        list = RemoveFromList("Sum_Model", list  ,";")
128       
129        tmp = FunctionList("*_proto",";","KIND:10")             //prototypes
130        list = RemoveFromList(tmp, list  ,";")
131
132//      Print list
133        tmp = GrepList(FunctionList("f*",";","KIND:10"),"^f")   
134//      tmp = FunctionList("f*",";","KIND:10")          //point calculations
135       
136//      Print tmp
137       
138        list = RemoveFromList(tmp, list  ,";")
139       
140        // this should be a null string with KIND:10
141        tmp = FunctionList("*X",";","KIND:10")          //XOPs, also point calculations
142        list = RemoveFromList(tmp, list  ,";")
143       
144        // remove some odds and ends...
145        tmp = "UpdateQxQy2Mat;"
146        tmp += "MakeBSMask;"
147        list = RemoveFromList(tmp, list  ,";")
148       
149        return(list)
150End
151
152// show all the appropriate coefficient waves
153Function/S CoefPopupList()
154        String list
155        list = WaveList("coef*",";","")
156        list = RemoveFromList("coef_sum", list  ,";")
157        return(list)
158End
159
160//button procedure
161Function PlotSumButtonProc(ctrlName) : ButtonControl
162        String ctrlName
163
164        Execute "PlotSum_Model()"
165End
166
167//button procedure
168Function PlotSmearedSumButtonProc(ctrlName) : ButtonControl
169        String ctrlName
170
171        Execute "PlotSmeared_Sum_Model()"
172End
173
174Function Sum_HelpButtonProc(ctrlName) : ButtonControl
175        String ctrlName
176        DisplayHelpTopic/Z/K=1 "Sum SANS Models"
177        if(V_flag != 0)
178                DoAlert 0, "The Sum SANS Models Help file can not be found"
179        endif
180End
181
182//////////////////////////////
183
184
185// this is the procedure that sets up the plot, just like
186// a normal procedure for a model function
187// - there's just a bit more going on, since it needs to
188// build things up based on the settings of the panel
189Proc PlotSum_Model(num,qmin,qmax)                                               
190        Variable num=128,qmin=0.001,qmax=0.7
191        Prompt num "Enter number of data points for model: "
192        Prompt qmin "Enter minimum q-value (A^-1) for model: "
193        Prompt qmax "Enter maximum q-value (A^-1) for model: "
194       
195        Make/O/D/n=(num) xwave_sum,ywave_sum                                   
196        xwave_sum = alog(log(qmin) + x*((log(qmax)-log(qmin))/num))
197       
198        //make the coefficients and parameters based on the panel values       
199        Variable nParam,n1,n2
200        n1 = root:Packages:NIST:SumModel:gNParMod1
201        n2 = root:Packages:NIST:SumModel:gNParMod2
202        nParam = n1 + n2
203        if(n1==0 || n2==0 || nparam==0)
204                Abort "# of parameters must not be zero"
205        endif
206        // n is ok, keep extra copy so changing panel will not affect functions
207        Variable/G root:Packages:NIST:SumModel:gN1=n1
208        Variable/G root:Packages:NIST:SumModel:gN2=n2
209       
210        // these are the function names - make global so the fit function
211        // can find them
212        ControlInfo/W=Sum_Model_Panel popup1_0
213        String/G root:Packages:NIST:SumModel:gModelStr1=S_Value
214        ControlInfo/W=Sum_Model_Panel popup2_0
215        String/G root:Packages:NIST:SumModel:gModelStr2=S_Value
216       
217        //these are the coefficent waves - local only
218        ControlInfo/W=Sum_Model_Panel popup1_1
219        String/G root:coefStr1=S_Value
220        ControlInfo/W=Sum_Model_Panel popup2_1
221        String/G root:coefStr2=S_Value
222       
223        Make/O/D/N=(nParam) coef_sum   
224        coef_sum[0,(n1-1)] = $coefStr1
225        coef_sum[n1,(n1+n2-1)] = $coefStr2[p-n1]
226                                               
227        make/o/t/N=(nParam) parameters_sum
228        String paramStr1 = "parameters"+coefStr1[4,strlen(coefStr1)-1]
229        String paramStr2 = "parameters"+coefStr2[4,strlen(coefStr2)-1]
230        parameters_sum[0,(n1-1)] = $paramStr1
231        parameters_sum[n1,(n1+n2-1)] = $paramStr2[p-n1]
232       
233        Edit parameters_sum,coef_sum
234       
235        Variable/G root:g_sum
236        g_sum := Sum_Model(coef_sum,ywave_sum,xwave_sum)                       
237        Display ywave_sum vs xwave_sum                                                 
238        ModifyGraph log=1,marker=29,msize=2,mode=4                     
239        Label bottom "q (A\\S-1\\M)"
240        Label left "Intensity (cm\\S-1\\M)"
241        Legend                                 
242        AutoPositionWindow/M=1/R=$(WinName(0,1)) $WinName(0,2)
243       
244        AddModelToStrings("Sum_Model","coef_sum","parameters_sum","sum")
245       
246        // additional step to make sure the "helper waves" are the right dimension, in case the user
247        // has changed the functions (M. Laver)
248        // if it exists here, redimension. otherwise, let the Wrapper create it
249        String suffix = "sum"
250        if(exists("Hold_"+suffix) == 1)
251                Redimension/N=(nParam) $("epsilon_"+suffix),$("Hold_"+suffix)
252                Redimension/N=(nParam) $("LoLim_"+suffix),$("HiLim_"+suffix)
253                $("epsilon_"+suffix) = abs(coef_sum*1e-4) + 1e-10                       //default eps is proportional to the coefficients
254        endif
255End
256
257// - sets up a dependency to a wrapper, not the actual SmearedModelFunction
258// the usual macro for plotting the smeared model, updated
259// to take input from the panel
260//
261// - somewhat confusing as the unsmeared coefficients are in root:
262// and all of the newly created smeared waves and coefficients are in the
263// selected data folder
264//
265Proc PlotSmeared_Sum_Model(str)                                                         
266        String str
267        Prompt str,"Pick the data folder containing the resolution you want",popup,getAList(4)
268       
269        // if any of the resolution waves are missing => abort
270        if(ResolutionWavesMissingDF(str))               //updated to NOT use global strings (in GaussUtils)
271                Abort
272        endif
273       
274        SetDataFolder $("root:"+str)
275       
276        //make the coefficients and parameters based on the panel values       
277        Variable nParam,n1,n2
278        n1 = root:Packages:NIST:SumModel:gNParMod1
279        n2 = root:Packages:NIST:SumModel:gNParMod2
280        nParam = n1 + n2
281        if(n1==0 || n2==0 || nparam==0)
282                Abort "# of parameters must not be zero"
283        endif
284        // n is ok, keep extra copy so changing panel will not affect functions
285        Variable/G root:Packages:NIST:SumModel:gN1=n1
286        Variable/G root:Packages:NIST:SumModel:gN2=n2
287       
288        // these are the function names - make global so the fit function
289        // can find them
290        ControlInfo/W=Sum_Model_Panel popup1_0
291        String/G root:Packages:NIST:SumModel:gModelStr1=S_Value
292        ControlInfo/W=Sum_Model_Panel popup2_0
293        String/G root:Packages:NIST:SumModel:gModelStr2=S_Value
294       
295        //these are the coefficent waves - local only, in the current data folder!
296        ControlInfo/W=Sum_Model_Panel popup1_1
297        String/G coefStr1=S_Value
298        ControlInfo/W=Sum_Model_Panel popup2_1
299        String/G coefStr2=S_Value
300       
301        Make/O/D/N=(nParam) smear_coef_sum     
302        smear_coef_sum[0,(n1-1)] = $("root:"+coefStr1)
303        smear_coef_sum[n1,(n1+n2-1)] = $("root:"+coefStr2)[p-n1]
304                                               
305        make/o/t/N=(nParam) smear_parameters_sum
306        String paramStr1 = "parameters"+coefStr1[4,strlen(coefStr1)-1]
307        String paramStr2 = "parameters"+coefStr2[4,strlen(coefStr2)-1]
308        smear_parameters_sum[0,(n1-1)] = $("root:"+paramStr1)
309        smear_parameters_sum[n1,(n1+n2-1)] = $("root:"+paramStr2)[p-n1]
310                               
311        Edit smear_parameters_sum,smear_coef_sum                                       
312       
313        // output smeared intensity wave, dimensions are identical to experimental QSIG values
314        // make extra copy of experimental q-values for easy plotting
315        Duplicate/O $(str+"_q") smeared_sum,smeared_qvals                               
316        SetScale d,0,0,"1/cm",smeared_sum                                                       
317                                       
318        Variable/G gs_sum=0
319        gs_sum := fSmeared_Sum_Model(smear_coef_sum,smeared_sum,smeared_qvals)  //this wrapper fills the STRUCT
320       
321        Display smeared_sum vs $(str+"_q")                                                                     
322        ModifyGraph log=1,marker=29,msize=2,mode=4
323        Label bottom "q (A\\S-1\\M)"
324        Label left "Intensity (cm\\S-1\\M)"
325        Legend
326        AutoPositionWindow/M=1/R=$(WinName(0,1)) $WinName(0,2)
327       
328        SetDataFolder root:
329        AddModelToStrings("Smeared_Sum_Model","smear_coef_sum","smear_parameters_sum","sum")
330       
331        // additional step to make sure the "helper waves" are the right dimension, in case the user
332        // has changed the functions (M. Laver)
333        SetDataFolder $("root:"+str)
334        String suffix = "sum"
335        if(exists("Hold_"+suffix) == 1)
336                Redimension/N=(nParam) $("epsilon_"+suffix),$("Hold_"+suffix)
337                Redimension/N=(nParam) $("LoLim_"+suffix),$("HiLim_"+suffix)
338                $("epsilon_"+suffix) = abs(smear_coef_sum*1e-4) + 1e-10                 //default eps is proportional to the coefficients
339        endif
340        SetDataFolder root:
341End
342
343
344// this is the actual fitting function that is the
345// sum of the two selected models.
346//
347// this is an AAO function, there is no XOP version
348// since it should be the sum of two XOPs
349//
350Function Sum_Model(w,yw,xw) : FitFunc
351        Wave w,yw,xw
352       
353        SVAR funcStr1=root:Packages:NIST:SumModel:gModelStr1            //string names of the functions, set by the macro
354        SVAR funcStr2=root:Packages:NIST:SumModel:gModelStr2
355        NVAR n1=root:Packages:NIST:SumModel:gN1                 //number of coefficients, set by the macro
356        NVAR n2=root:Packages:NIST:SumModel:gN2
357       
358        Variable retVal
359       
360        FUNCREF SANSModelAAO_proto f1 = $funcStr1               //convert str to FCN
361        FUNCREF SANSModelAAO_proto f2 = $funcStr2
362        // make temporary coefficient waves for each model
363        Make/O/D/N=(n1) temp_cw1
364        Make/O/D/N=(n2) temp_cw2
365        temp_cw1 = w[p]
366        temp_cw2 = w[p+n1]
367       
368        // calculate the sum of each of the AAO functions
369        Duplicate/O xw tmp_sum_yw1,tmp_sum_yw2
370       
371        f1(temp_cw1,tmp_sum_yw1,xw)
372        f2(temp_cw2,tmp_sum_yw2,xw)
373        yw = tmp_sum_yw1 + tmp_sum_yw2
374       
375        return(0)
376end
377
378// this is all there is to the smeared calculation!
379Function Smeared_Sum_Model(s) : FitFunc
380        Struct ResSmearAAOStruct &s
381
382//      the name of your unsmeared model (AAO) is the first argument
383        Smear_Model_20(Sum_Model,s.coefW,s.xW,s.yW,s.resW)
384
385        return(0)
386End
387
388//wrapper to calculate the smeared model as an AAO-Struct
389// fills the struct and calls the ususal function with the STRUCT parameter
390//
391// used only for the dependency, not for fitting
392//
393Function fSmeared_Sum_Model(coefW,yW,xW)
394        Wave coefW,yW,xW
395       
396        String str = getWavesDataFolder(yW,0)
397        String DF="root:"+str+":"
398       
399        WAVE resW = $(DF+str+"_res")
400       
401        STRUCT ResSmearAAOStruct fs
402        WAVE fs.coefW = coefW   
403        WAVE fs.yW = yW
404        WAVE fs.xW = xW
405        WAVE fs.resW = resW
406       
407        Variable err
408        err = Smeared_Sum_Model(fs)
409       
410        return (0)
411End
412
413//procedures to clean up after itself
414Function UnloadSumModel()
415        if (WinType("Sum_Model_Panel") == 7)
416                DoWindow/K Sum_Model_Panel
417        endif
418        SVAR fileVerExt=root:Packages:NIST:SANS_ANA_EXTENSION
419        String fname="SumSANSModels"
420        Execute/P "DELETEINCLUDE \""+fname+fileVerExt+"\""
421        Execute/P "COMPILEPROCEDURES "
422end
423
424Menu "SANS Models"
425        Submenu "Packages"
426                "Unload Sum SANS Models", UnloadSumModel()
427        End
428end
Note: See TracBrowser for help on using the repository browser.