source: sans/Dev/trunk/NCNR_User_Procedures/Analysis/Models/NewModels_2008/LamellarParacrystal_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: 6.7 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma IgorVersion=6.1
3
4////////////////////////////////////////////////////
5//
6// paracrystalline model of Lamellar stacks from J. Pedersen
7//
8// non-integer # of stacks are calculated as linear combination of trunc(N) and trunc(N+1)
9//
10// References:
11// - J. Appl. cryst. 30 (1997) 975.
12// - JPC B 103 (1999) 9888-9897.
13//
14////////////////////////////////////////////////////
15
16//
17Proc PlotLamellar_ParaCrystal(num,qmin,qmax)
18        Variable num=200, qmin=0.001, qmax=0.7
19        Prompt num "Enter number of data points for model: "
20        Prompt qmin "Enter minimum q-value (^-1) for model: "
21        Prompt qmax "Enter maximum q-value (^-1) for model: "
22//
23        Make/O/D/n=(num) xwave_LamParaCryst, ywave_LamParaCryst
24        xwave_LamParaCryst =  alog(log(qmin) + x*((log(qmax)-log(qmin))/num))
25        Make/O/D coef_LamParaCryst = {1,33,20,250,0.2,1e-6,6.34e-6,0}           
26        make/o/t parameters_LamParaCryst = {"scale","Lamellar thickness (A)","N Layers","layer spacing (A)","polydisp of spacing","SLD of Layer (A-2)","SLD of solvent (A-2)","Incoherent Bgd (cm-1)"}  //CH#2
27        Edit parameters_LamParaCryst, coef_LamParaCryst
28       
29        Variable/G root:g_LamParaCryst
30        g_LamParaCryst := Lamellar_ParaCrystal(coef_LamParaCryst, ywave_LamParaCryst, xwave_LamParaCryst)
31        Display ywave_LamParaCryst vs xwave_LamParaCryst
32        ModifyGraph marker=29, msize=2, mode=4
33        ModifyGraph log=1,grid=1,mirror=2
34        Label bottom "q (\\S-1\\M) "
35        Label left "I(q) (cm\\S-1\\M)"
36        AutoPositionWindow/M=1/R=$(WinName(0,1)) $WinName(0,2)
37       
38        AddModelToStrings("Lamellar_ParaCrystal","coef_LamParaCryst","parameters_LamParaCryst","LamParaCryst")
39//
40End
41
42
43//
44//no input parameters are necessary, it MUST use the experimental q-values
45// from the experimental data read in from an AVE/QSIG data file
46////////////////////////////////////////////////////
47// - sets up a dependency to a wrapper, not the actual SmearedModelFunction
48Proc PlotSmearedLamellar_ParaCrystal(str)                                                               
49        String str
50        Prompt str,"Pick the data folder containing the resolution you want",popup,getAList(4)
51       
52        // if any of the resolution waves are missing => abort
53        if(ResolutionWavesMissingDF(str))               //updated to NOT use global strings (in GaussUtils)
54                Abort
55        endif
56       
57        SetDataFolder $("root:"+str)
58       
59        // Setup parameter table for model function
60        Make/O/D smear_coef_LamParaCryst = {1,33,20,250,0.2,1e-6,6.34e-6,0}             
61        make/o/t smear_parameters_LamParaCryst = {"scale","Lamellar thickness (A)","N Layers","layer spacing (A)","polydisp of spacing","SLD of Layer (A-2)","SLD of solvent (A-2)","Incoherent Bgd (cm-1)"}
62        Edit smear_parameters_LamParaCryst,smear_coef_LamParaCryst                                      //display parameters in a table
63       
64        // output smeared intensity wave, dimensions are identical to experimental QSIG values
65        // make extra copy of experimental q-values for easy plotting
66        Duplicate/O $(str+"_q") smeared_LamParaCryst,smeared_qvals
67        SetScale d,0,0,"1/cm",smeared_LamParaCryst
68                                       
69        Variable/G gs_LamParaCryst=0
70        gs_LamParaCryst := fSmearedLamellar_ParaCrystal(smear_coef_LamParaCryst,smeared_LamParaCryst,smeared_qvals)     //this wrapper fills the STRUCT
71       
72        Display smeared_LamParaCryst vs smeared_qvals
73        ModifyGraph log=1,marker=29,msize=2,mode=4
74        Label bottom "q (\\S-1\\M)"
75        Label left "I(q) (cm\\S-1\\M)"
76        AutoPositionWindow/M=1/R=$(WinName(0,1)) $WinName(0,2)
77       
78        SetDataFolder root:
79        AddModelToStrings("SmearedLamellar_ParaCrystal","smear_coef_LamParaCryst","smear_parameters_LamParaCryst","LamParaCryst")
80End
81
82
83//
84//AAO version, uses XOP if available
85// simply calls the original single point calculation with
86// a wave assignment (this will behave nicely if given point ranges)
87Function Lamellar_ParaCrystal(cw,yw,xw) : FitFunc
88        Wave cw,yw,xw
89       
90#if exists("Lamellar_ParaCrystalX")
91        yw = Lamellar_ParaCrystalX(cw,xw)
92#else
93        yw = fLamellar_ParaCrystal(cw,xw)
94#endif
95        return(0)
96End
97
98//
99// unsmeared model calculation
100//
101Function fLamellar_ParaCrystal(w,x) : FitFunc
102        Wave w
103        Variable x
104       
105//       Input (fitting) variables are:
106        //[0] scale factor
107        //[1]   thickness
108        //[2]   number of layers
109        //[3]   spacing between layers
110        //[4]   polydispersity of spacing
111        //[5] SLD lamellar
112        //[6] SLD solvent
113        //[7] incoherent background
114//      give them nice names
115        Variable inten,qval,scale,th,nl,davg,pd,contr,bkg
116        Variable xi,ww,Pbil,Zq,Znq,Snq,an,sldLayer,sldSolvent
117       
118        scale = w[0]
119        th = w[1]
120        nl = w[2]
121        davg = w[3]
122        pd = w[4]
123        sldLayer = w[5]
124        sldSolvent = w[6]
125        bkg = w[7]
126       
127        contr = w[5] - w[6]
128        qval = x
129               
130        //get the fractional part of nl, to determine the "mixing" of N's
131        Variable n1,n2,xn
132       
133        n1 = trunc(nl)          //rounds towards zero
134        n2 = n1 + 1
135        xn = n2 - nl                    //fractional contribution of n1
136       
137        ww = exp(-qval*qval*pd*pd*davg*davg/2)
138       
139        //calculate the n1 contribution
140        an = paraCryst_an(ww,qval,davg,n1)
141        Snq = paraCryst_sn(ww,qval,davg,n1,an)
142       
143        Znq = xn*Snq
144       
145        //calculate the n2 contribution
146        an = paraCryst_an(ww,qval,davg,n2)
147        Snq = paraCryst_sn(ww,qval,davg,n2,an)
148       
149        Znq += (1-xn)*Snq
150       
151        //and the independent contribution
152        Znq += (1-ww^2)/(1+ww^2-2*ww*cos(qval*davg))
153       
154        //the limit when NL approaches infinity
155//      Zq = (1-ww^2)/(1+ww^2-2*ww*cos(qval*davg))
156       
157        xi = th/2               //use 1/2 the bilayer thickness
158        Pbil = (sin(qval*xi)/(qval*xi))^2
159       
160        inten = 2*pi*contr*contr*Pbil*Znq/qval^2
161        inten *= 1e8
162       
163        Return (scale*inten+bkg)
164End
165
166Function paraCryst_sn(ww,qval,davg,nl,an)
167        Variable ww,qval,davg,nl,an
168       
169        Variable snq
170        Snq = an/(nl*(1+ww^2-2*ww*cos(qval*davg))^2)
171        return(snq)
172end
173
174
175Function paraCryst_an(ww,qval,davg,nl)
176        Variable ww,qval,davg,nl
177       
178        Variable an
179        an = 4*ww^2 - 2*(ww^3+ww)*cos(qval*davg)
180        an -= 4*ww^(nl+2)*cos(nl*qval*davg)
181        an += 2*ww^(nl+3)*cos((nl-1)*qval*davg)
182        an += 2*ww^(nl+1)*cos((nl+1)*qval*davg)
183        return(an)
184end
185
186
187///////////////////////////////////////////////////////////////
188// smeared model calculation
189//
190// you don't need to do anything with this function, as long as
191// your Lamellar_ParaCrystal works correctly, you get the resolution-smeared
192// version for free.
193//
194// this is all there is to the smeared model calculation!
195Function SmearedLamellar_ParaCrystal(s) : FitFunc
196        Struct ResSmearAAOStruct &s
197
198//      the name of your unsmeared model (AAO) is the first argument
199        Smear_Model_20(Lamellar_ParaCrystal,s.coefW,s.xW,s.yW,s.resW)
200
201        return(0)
202End
203
204
205///////////////////////////////////////////////////////////////
206
207
208// nothing to change here
209//
210//wrapper to calculate the smeared model as an AAO-Struct
211// fills the struct and calls the ususal function with the STRUCT parameter
212//
213// used only for the dependency, not for fitting
214//
215Function fSmearedLamellar_ParaCrystal(coefW,yW,xW)
216        Wave coefW,yW,xW
217       
218        String str = getWavesDataFolder(yW,0)
219        String DF="root:"+str+":"
220       
221        WAVE resW = $(DF+str+"_res")
222       
223        STRUCT ResSmearAAOStruct fs
224        WAVE fs.coefW = coefW   
225        WAVE fs.yW = yW
226        WAVE fs.xW = xW
227        WAVE fs.resW = resW
228       
229        Variable err
230        err = SmearedLamellar_ParaCrystal(fs)
231       
232        return (0)
233End
Note: See TracBrowser for help on using the repository browser.