-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpeakModel.pro
More file actions
202 lines (186 loc) · 6.59 KB
/
Copy pathpeakModel.pro
File metadata and controls
202 lines (186 loc) · 6.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
; *******************************************************************
; Multfit efficient processing of 2D diffraction images
; Copyright (C) 2000-2014 S. Merkel, Universite Lille 1
; http://merkel.zoneo.net/Multifit/
;
; This program is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation; either version 2
; of the License, or (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
;
; *******************************************************************
; data range (array of integers)
; number of peaks
; array of objects peaks
PRO PeakModel__DEFINE
struct = { PeakModel, nterms : 0, peakprofile:0, thistwotheta: PTR_NEW(), thisintensity: PTR_NEW(), thishwidth: PTR_NEW(), thisweightGL: PTR_NEW() }
END
; Init method
function PeakModel::Init
self.nterms = 15
return, 1
end
; Cleanup method
pro PeakModel::Cleanup
end
FUNCTION PeakModel::setPeakProfile, profile
self.peakprofile=profile
if (profile eq 1) then test = self->initPseudoVoigt()
return, 1
end
FUNCTION PeakModel::initPseudoVoigt
self.thisweightGL = PTR_NEW(fltarr(self.nterms*2+1))
(*self.thisweightGL)(0) = 0.5
for i=1, self.nterms*2 do begin
(*self.thisweightGL)(i) = 0.
endfor
return, 1
end
FUNCTION PeakModel::fromData, log, ndata, dataazimuth, datatwotheta, dataintensity, datahwidth
; Creating peak models: Fourier transform of experimental data
self.thistwotheta = PTR_NEW(fltarr(self.nterms*2+1))
self.thisintensity = PTR_NEW(fltarr(self.nterms*2+1))
self.thishwidth = PTR_NEW(fltarr(self.nterms*2+1))
az = dataazimuth(0:(ndata-1))*!pi/360.
theta = datatwotheta(0:(ndata-1))
int = dataintensity(0:(ndata-1))
w = datahwidth(0:(ndata-1))
; Model for 2 theta
sigma = 0.0001*(theta)
guess = fltarr(self.nterms*2+1)
guess[0] = mean(theta)
*(self.thistwotheta) = MPFITFUN('FOURIER', az, theta, sigma, guess, /quiet)
logit, log, ' 2 theta model is ready'
; Model for intensities
sigma = 0.0001*(int)
guess = fltarr(self.nterms*2+1)
guess[0] = mean(int)
*(self.thisintensity) = MPFITFUN('FOURIER', az, int, sigma, guess, /quiet)
logit, log, ' Intensity model is ready'
; Model for peak width
sigma = 0.0001*(w)
guess = fltarr(self.nterms*2+1)
guess[0] = mean(w)
*(self.thishwidth) = MPFITFUN('FOURIER', az, w, sigma, guess, /quiet)
logit, log, ' Half-width model is ready'
RETURN, 1
END
FUNCTION PeakModel::fromDataNoLog, ndata, dataazimuth, datatwotheta, dataintensity, datahwidth
; Creating peak models: Fourier transform of experimental data
self.thistwotheta = PTR_NEW(fltarr(self.nterms*2+1))
self.thisintensity = PTR_NEW(fltarr(self.nterms*2+1))
self.thishwidth = PTR_NEW(fltarr(self.nterms*2+1))
az = dataazimuth(0:(ndata-1))*!pi/360.
theta = datatwotheta(0:(ndata-1))
int = dataintensity(0:(ndata-1))
w = datahwidth(0:(ndata-1))
; Model for 2 theta
sigma = 0.0001*(theta)
guess = fltarr(self.nterms*2+1)
guess[0] = mean(theta)
*(self.thistwotheta) = MPFITFUN('FOURIER', az, theta, sigma, guess, /quiet)
; Model for intensities
sigma = 0.0001*(int)
guess = fltarr(self.nterms*2+1)
guess[0] = mean(int)
*(self.thisintensity) = MPFITFUN('FOURIER', az, int, sigma, guess, /quiet)
; Model for peak width
sigma = 0.0001*(w)
guess = fltarr(self.nterms*2+1)
guess[0] = mean(w)
*(self.thishwidth) = MPFITFUN('FOURIER', az, w, sigma, guess, /quiet)
RETURN, 1
END
; Fit of the weight between gaussian and lorentzian. It is put separatly
; it is only use with the pseudo-voigt peak profile
FUNCTION PeakModel::fitWeightGL, ndata, dataazimuth, dataweightgl
self.thisweightGL = PTR_NEW(fltarr(self.nterms*2+1))
az = dataazimuth(0:(ndata-1))*!pi/360.
we = dataweightgl(0:(ndata-1))
sigma = (we)+0.01
guess = fltarr(self.nterms*2+1)
guess[0] = mean(we)
*(self.thisweightGL) = MPFITFUN('FOURIER', az, we, sigma, guess, /quiet)
RETURN, 1
END
FUNCTION PeakModel::intensity, az
; print, "Here, PeakModel::intensity", az
y = fourier(az*!pi/360., *(self.thisintensity))
; print, "ready to return, PeakModel::intensity", az
; print, "Returning:intensity ", y
return, y
END
FUNCTION PeakModel::twotetha, az
; print, "Here, PeakModel::twotetha", az
y = fourier(az*!pi/360., *(self.thistwotheta))
; print, "ready to return, PeakModel::twotetha", az
; print, "Returning: ", y
return, y
END
FUNCTION PeakModel::hwidth, az
y = fourier(az*!pi/360., *(self.thishwidth))
return, y
END
FUNCTION PeakModel::weightGL, az
y = fourier(az*!pi/360., *(self.thisweightGL))
return, y
END
FUNCTION PeakModel::readFromAscii, lun
on_ioerror, bad
self.nterms = fix(readascii(lun,com="#"))
self.peakprofile = fix(readascii(lun,com="#"))
self.thistwotheta = PTR_NEW(fltarr(self.nterms*2+1))
self.thisintensity = PTR_NEW(fltarr(self.nterms*2+1))
self.thishwidth = PTR_NEW(fltarr(self.nterms*2+1))
self.thisweightGL = PTR_NEW(fltarr(self.nterms*2+1))
for i=0, self.nterms*2 do begin
(*self.thistwotheta)(i) = float(readascii(lun,com='#'))
endfor
for i=0, self.nterms*2 do begin
(*self.thisintensity)(i) = float(readascii(lun,com='#'))
endfor
for i=0, self.nterms*2 do begin
(*self.thishwidth)(i) = float(readascii(lun,com='#'))
endfor
if (self.peakprofile eq 1) then begin
for i=0, self.nterms*2 do begin
(*self.thisweightGL)(i) = float(readascii(lun,com='#'))
endfor
endif
RETURN, 1
bad: return, !ERR_STRING
END
FUNCTION PeakModel::saveToAscii, lun
printf, lun, '# Number terms in Fourier expension'
printf, lun, STRING(self.nterms, /PRINT)
printf, lun, '# Peak profile: 0- Gauss 1-Pseudo Voigt 2-Lorentz'
printf, lun, STRING(self.peakprofile, /PRINT)
printf, lun, '# Fourier coefficients for 2 theta'
for i=0, self.nterms*2 do begin
printf, lun, STRING((*self.thistwotheta)(i), /PRINT)
endfor
printf, lun, '# Fourier coefficients for intensities'
for i=0, self.nterms*2 do begin
printf, lun, STRING((*self.thisintensity)(i), /PRINT)
endfor
printf, lun, '# Fourier coefficients for half-widths'
for i=0, self.nterms*2 do begin
printf, lun, STRING((*self.thishwidth)(i), /PRINT)
endfor
if (self.peakprofile eq 1) then begin
printf, lun, '# Fourier coefficients for weight between Gauss and Lorentz'
for i=0, self.nterms*2 do begin
printf, lun, STRING((*self.thisweightGL)(i), /PRINT)
endfor
endif
RETURN, 1
END