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

Last change on this file since 939 was 939, checked in by srkline, 9 years ago

correcting typos in U_CALC and SumSANSModels

File size: 13.3 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       
126        //get every user defined curve fit function, remove everything the user doesn't need to see...
127        list = User_FunctionPopupList() + "EC_Empirical;"
128       
129        // must remove Sum_Model
130        list = RemoveFromList("Sum_Model", list  ,";")
131
132//      can remove the smeared models either this way, or using GrepList as below
133//      tmp = FunctionList("Smear*",";","KIND:10")              //don't show smeared models
134//      list = RemoveFromList(tmp, list  ,";")
135
136//
137////    Print list
138        tmp = GrepList(list,"^Smear")                   //don't show the Smeared... models in the popup
139//      Print tmp       
140        list = RemoveFromList(tmp, list  ,";")
141//     
142       
143        return(list)
144End
145
146// show all the appropriate coefficient waves
147Function/S CoefPopupList()
148        String list
149        list = WaveList("coef*",";","")
150        list = RemoveFromList("coef_sum", list  ,";")
151        return(list)
152End
153
154//button procedure
155Function PlotSumButtonProc(ctrlName) : ButtonControl
156        String ctrlName
157
158        Execute "PlotSum_Model()"
159End
160
161//button procedure
162Function PlotSmearedSumButtonProc(ctrlName) : ButtonControl
163        String ctrlName
164
165        Execute "PlotSmearedSum_Model()"
166End
167
168Function Sum_HelpButtonProc(ctrlName) : ButtonControl
169        String ctrlName
170        DisplayHelpTopic/Z/K=1 "Sum SANS Models"
171        if(V_flag != 0)
172                DoAlert 0, "The Sum SANS Models Help file can not be found"
173        endif
174End
175
176//////////////////////////////
177
178
179// this is the procedure that sets up the plot, just like
180// a normal procedure for a model function
181// - there's just a bit more going on, since it needs to
182// build things up based on the settings of the panel
183Proc PlotSum_Model(num,qmin,qmax)                                               
184        Variable num=128,qmin=0.001,qmax=0.7
185        Prompt num "Enter number of data points for model: "
186        Prompt qmin "Enter minimum q-value (A^-1) for model: "
187        Prompt qmax "Enter maximum q-value (A^-1) for model: "
188       
189        Make/O/D/n=(num) xwave_sum,ywave_sum                                   
190        xwave_sum = alog(log(qmin) + x*((log(qmax)-log(qmin))/num))
191       
192        //make the coefficients and parameters based on the panel values       
193        Variable nParam,n1,n2
194        n1 = root:Packages:NIST:SumModel:gNParMod1
195        n2 = root:Packages:NIST:SumModel:gNParMod2
196        nParam = n1 + n2
197        if(n1==0 || n2==0 || nparam==0)
198                Abort "# of parameters must not be zero"
199        endif
200        // n is ok, keep extra copy so changing panel will not affect functions
201        Variable/G root:Packages:NIST:SumModel:gN1=n1
202        Variable/G root:Packages:NIST:SumModel:gN2=n2
203       
204        // these are the function names - make global so the fit function
205        // can find them
206        ControlInfo/W=Sum_Model_Panel popup1_0
207        String/G root:Packages:NIST:SumModel:gModelStr1=S_Value
208        ControlInfo/W=Sum_Model_Panel popup2_0
209        String/G root:Packages:NIST:SumModel:gModelStr2=S_Value
210       
211        //these are the coefficent waves - local only
212        ControlInfo/W=Sum_Model_Panel popup1_1
213        String/G root:coefStr1=S_Value
214        ControlInfo/W=Sum_Model_Panel popup2_1
215        String/G root:coefStr2=S_Value
216       
217        Make/O/D/N=(nParam) coef_sum   
218        coef_sum[0,(n1-1)] = $coefStr1
219        coef_sum[n1,(n1+n2-1)] = $coefStr2[p-n1]
220                                               
221        make/o/t/N=(nParam) parameters_sum
222        String paramStr1 = "parameters"+coefStr1[4,strlen(coefStr1)-1]
223        String paramStr2 = "parameters"+coefStr2[4,strlen(coefStr2)-1]
224        parameters_sum[0,(n1-1)] = $paramStr1
225        parameters_sum[n1,(n1+n2-1)] = $paramStr2[p-n1]
226       
227        Edit parameters_sum,coef_sum
228       
229        Variable/G root:g_sum
230        g_sum := Sum_Model(coef_sum,ywave_sum,xwave_sum)                       
231        Display ywave_sum vs xwave_sum                                                 
232        ModifyGraph log=1,marker=29,msize=2,mode=4                     
233        Label bottom "q (A\\S-1\\M)"
234        Label left "Intensity (cm\\S-1\\M)"
235        Legend                                 
236        AutoPositionWindow/M=1/R=$(WinName(0,1)) $WinName(0,2)
237       
238        AddModelToStrings("Sum_Model","coef_sum","parameters_sum","sum")
239       
240        // additional step to make sure the "helper waves" are the right dimension, in case the user
241        // has changed the functions (M. Laver)
242        // if it exists here, redimension. otherwise, let the Wrapper create it
243        String suffix = "sum"
244        if(exists("Hold_"+suffix) == 1)
245                Redimension/N=(nParam) $("epsilon_"+suffix),$("Hold_"+suffix)
246                Redimension/N=(nParam) $("LoLim_"+suffix),$("HiLim_"+suffix)
247                $("epsilon_"+suffix) = abs(coef_sum*1e-4) + 1e-10                       //default eps is proportional to the coefficients
248        endif
249End
250
251// - sets up a dependency to a wrapper, not the actual SmearedModelFunction
252// the usual macro for plotting the smeared model, updated
253// to take input from the panel
254//
255// - somewhat confusing as the unsmeared coefficients are in root:
256// and all of the newly created smeared waves and coefficients are in the
257// selected data folder
258//
259Proc PlotSmearedSum_Model(str)                                                         
260        String str
261        Prompt str,"Pick the data folder containing the resolution you want",popup,getAList(4)
262       
263        // if any of the resolution waves are missing => abort
264        if(ResolutionWavesMissingDF(str))               //updated to NOT use global strings (in GaussUtils)
265                Abort
266        endif
267       
268        SetDataFolder $("root:"+str)
269       
270        //make the coefficients and parameters based on the panel values       
271        Variable nParam,n1,n2
272        n1 = root:Packages:NIST:SumModel:gNParMod1
273        n2 = root:Packages:NIST:SumModel:gNParMod2
274        nParam = n1 + n2
275        if(n1==0 || n2==0 || nparam==0)
276                Abort "# of parameters must not be zero"
277        endif
278        // n is ok, keep extra copy so changing panel will not affect functions
279        Variable/G root:Packages:NIST:SumModel:gN1=n1
280        Variable/G root:Packages:NIST:SumModel:gN2=n2
281       
282        // these are the function names - make global so the fit function
283        // can find them
284        ControlInfo/W=Sum_Model_Panel popup1_0
285        String/G root:Packages:NIST:SumModel:gModelStr1=S_Value
286        ControlInfo/W=Sum_Model_Panel popup2_0
287        String/G root:Packages:NIST:SumModel:gModelStr2=S_Value
288       
289        //these are the coefficent waves - local only, in the current data folder!
290        ControlInfo/W=Sum_Model_Panel popup1_1
291        String/G coefStr1=S_Value
292        ControlInfo/W=Sum_Model_Panel popup2_1
293        String/G coefStr2=S_Value
294       
295        Make/O/D/N=(nParam) smear_coef_sum     
296        smear_coef_sum[0,(n1-1)] = $("root:"+coefStr1)
297        smear_coef_sum[n1,(n1+n2-1)] = $("root:"+coefStr2)[p-n1]
298                                               
299        make/o/t/N=(nParam) smear_parameters_sum
300        String paramStr1 = "parameters"+coefStr1[4,strlen(coefStr1)-1]
301        String paramStr2 = "parameters"+coefStr2[4,strlen(coefStr2)-1]
302        smear_parameters_sum[0,(n1-1)] = $("root:"+paramStr1)
303        smear_parameters_sum[n1,(n1+n2-1)] = $("root:"+paramStr2)[p-n1]
304                               
305        Edit smear_parameters_sum,smear_coef_sum                                       
306       
307        // output smeared intensity wave, dimensions are identical to experimental QSIG values
308        // make extra copy of experimental q-values for easy plotting
309        Duplicate/O $(str+"_q") smeared_sum,smeared_qvals                               
310        SetScale d,0,0,"1/cm",smeared_sum                                                       
311                                       
312        Variable/G gs_sum=0
313        gs_sum := fSmearedSum_Model(smear_coef_sum,smeared_sum,smeared_qvals)   //this wrapper fills the STRUCT
314       
315        Display smeared_sum vs $(str+"_q")                                                                     
316        ModifyGraph log=1,marker=29,msize=2,mode=4
317        Label bottom "q (A\\S-1\\M)"
318        Label left "Intensity (cm\\S-1\\M)"
319        Legend
320        AutoPositionWindow/M=1/R=$(WinName(0,1)) $WinName(0,2)
321       
322        SetDataFolder root:
323        AddModelToStrings("SmearedSum_Model","smear_coef_sum","smear_parameters_sum","sum")
324       
325        // additional step to make sure the "helper waves" are the right dimension, in case the user
326        // has changed the functions (M. Laver)
327        SetDataFolder $("root:"+str)
328        String suffix = "sum"
329        if(exists("Hold_"+suffix) == 1)
330                Redimension/N=(nParam) $("epsilon_"+suffix),$("Hold_"+suffix)
331                Redimension/N=(nParam) $("LoLim_"+suffix),$("HiLim_"+suffix)
332                $("epsilon_"+suffix) = abs(smear_coef_sum*1e-4) + 1e-10                 //default eps is proportional to the coefficients
333        endif
334        SetDataFolder root:
335End
336
337
338// this is the actual fitting function that is the
339// sum of the two selected models.
340//
341// this is an AAO function, there is no XOP version
342// since it should be the sum of two XOPs
343//
344Function Sum_Model(w,yw,xw) : FitFunc
345        Wave w,yw,xw
346       
347        SVAR funcStr1=root:Packages:NIST:SumModel:gModelStr1            //string names of the functions, set by the macro
348        SVAR funcStr2=root:Packages:NIST:SumModel:gModelStr2
349        NVAR n1=root:Packages:NIST:SumModel:gN1                 //number of coefficients, set by the macro
350        NVAR n2=root:Packages:NIST:SumModel:gN2
351       
352        Variable retVal
353       
354        FUNCREF SANSModelAAO_proto f1 = $funcStr1               //convert str to FCN
355        FUNCREF SANSModelAAO_proto f2 = $funcStr2
356        // make temporary coefficient waves for each model
357        Make/O/D/N=(n1) temp_cw1
358        Make/O/D/N=(n2) temp_cw2
359        temp_cw1 = w[p]
360        temp_cw2 = w[p+n1]
361       
362        // calculate the sum of each of the AAO functions
363        Duplicate/O xw tmp_sum_yw1,tmp_sum_yw2
364       
365        f1(temp_cw1,tmp_sum_yw1,xw)
366        f2(temp_cw2,tmp_sum_yw2,xw)
367        yw = tmp_sum_yw1 + tmp_sum_yw2
368       
369        return(0)
370end
371
372// this is all there is to the smeared calculation!
373Function SmearedSum_Model(s) : FitFunc
374        Struct ResSmearAAOStruct &s
375
376//      the name of your unsmeared model (AAO) is the first argument
377        Smear_Model_20(Sum_Model,s.coefW,s.xW,s.yW,s.resW)
378
379        return(0)
380End
381
382//wrapper to calculate the smeared model as an AAO-Struct
383// fills the struct and calls the ususal function with the STRUCT parameter
384//
385// used only for the dependency, not for fitting
386//
387Function fSmearedSum_Model(coefW,yW,xW)
388        Wave coefW,yW,xW
389       
390        String str = getWavesDataFolder(yW,0)
391        String DF="root:"+str+":"
392       
393        WAVE resW = $(DF+str+"_res")
394       
395        STRUCT ResSmearAAOStruct fs
396        WAVE fs.coefW = coefW   
397        WAVE fs.yW = yW
398        WAVE fs.xW = xW
399        WAVE fs.resW = resW
400       
401        Variable err
402        err = SmearedSum_Model(fs)
403       
404        return (0)
405End
406
407//procedures to clean up after itself
408Function UnloadSumModel()
409        if (WinType("Sum_Model_Panel") == 7)
410                DoWindow/K Sum_Model_Panel
411        endif
412        SVAR fileVerExt=root:Packages:NIST:SANS_ANA_EXTENSION
413        String fname="SumSANSModels"
414        Execute/P "DELETEINCLUDE \""+fname+fileVerExt+"\""
415        Execute/P "COMPILEPROCEDURES "
416end
417
418Menu "SANS Models"
419        Submenu "Packages"
420                "Unload Sum SANS Models", UnloadSumModel()
421        End
422end
Note: See TracBrowser for help on using the repository browser.