PEARL Procedures rev-distro-2.1.1-1-gf419e92-dirty Igor procedures for the analysis of PEARL data

pearl-fitfuncs.ipf
Go to the documentation of this file.
1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
2 #pragma IgorVersion = 6.2
3 #pragma ModuleName = PearlFitFuncs
4 #pragma version = 1.02
5 #include "mm-physconst"
6
20
25
26
27 //------------------------------------------------------------------------------
28 // Gaussian shapes
29 //------------------------------------------------------------------------------
30
44 threadsafe function MultiGaussLinBG(w,x) : FitFunc
45 wave w
46 variable x
47
48 variable np = numpnts(w)
49 variable ip
50
51 variable v = w[0] + x * w[1]
52 for (ip = 2; ip < np; ip += 3)
53 v += w[ip] * exp( -( (x - w[ip+1]) / w[ip+2] )^2 )
54 endfor
55
56 return v
57 end
58
79 threadsafe function MultiGaussLinBG_AO(pw, yw, xw) : FitFunc
80 wave pw
81 wave yw
82 wave xw
83
84 variable np = numpnts(pw)
85 variable ip
86
87 yw = pw[0] + xw[p] * pw[1]
88 for (ip = 2; ip < np; ip += 3)
89 yw += pw[ip] * exp( -( (xw[p] - pw[ip+1]) / pw[ip+2] )^2 )
90 endfor
91 end
92
117 threadsafe function DoubletGaussLinBG_AO(pw, yw, xw) : FitFunc
118 wave pw
119 wave yw
120 wave xw
121
122 yw = pw[0] + xw[p] * pw[1]
123 yw += pw[2] * exp( -( (xw[p] - pw[4] - pw[5] /2) / pw[6] )^2 )
124 yw += pw[2] * pw[3] * exp( -( (xw[p] - pw[4] + pw[5] /2) / pw[6] / pw[7] )^2 )
125 end
126
127 //------------------------------------------------------------------------------
128 // Voigt shapes
129 //------------------------------------------------------------------------------
130
144 function MultiVoigtLinBG(w,x) : FitFunc
145 wave w
146 variable x
147
148 variable np = numpnts(w)
149 variable ip
150
151 variable v = w[0] + x * w[1]
152 for (ip = 2; ip < np; ip += 4)
153 v += w[ip] * VoigtFunc((x - w[ip+1]) / w[ip+2], w[ip+3])
154 endfor
155
156 return v
157 end
158
159
160 //------------------------------------------------------------------------------
161 // Doniach-Sunjic shapes
162 //------------------------------------------------------------------------------
163
174 threadsafe function DoniachSunjic(x, amp, pos, sing, fwhm)
175 variable x
176 variable amp
177 variable pos
178 variable sing
179 variable fwhm
180
181 variable nom, denom
182 nom = cos(pi * sing / 2 + (1 - sing) * atan((x - pos) / fwhm * 2))
183 denom = ((x - pos)^2 + fwhm^2 / 4)^((1 - sing) / 2)
184
185 return amp * nom / denom * fwhm / 2
186 end
187
201 function MultiDoniachSunjicLinBG(w,x) : FitFunc
202 wave w
203 variable x
204
205 variable np = numpnts(w)
206 variable ip
207
208 variable v = w[0] + x * w[1]
209 for (ip = 2; ip < np; ip += 4)
210 v += DoniachSunjic(x, w[ip], w[ip+1], w[ip+3], w[ip+2])
211 endfor
212
213 return v
214 end
215
216
217 threadsafe function ds1_bg(w, x): FitFunc
218 // Doniach-Sunjic fit function
219 // 0 <= sing < 1
220 wave w // coefficients - see below
221 variable x // independent variable
222
223 //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
224 //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
225 //CurveFitDialog/ Equation:
226 //CurveFitDialog/ f(x) = DoniachSunjic(x, amp, pos, sing, fwhm) + bg
227 //CurveFitDialog/ End of Equation
228 //CurveFitDialog/ Independent Variables 1
229 //CurveFitDialog/ x
230 //CurveFitDialog/ Coefficients 5
231 //CurveFitDialog/ w[0] = bg
232 //CurveFitDialog/ w[1] = amp
233 //CurveFitDialog/ w[2] = pos
234 //CurveFitDialog/ w[3] = sing
235 //CurveFitDialog/ w[4] = FWHM
236
237 return DoniachSunjic(x, w[1], w[2], w[3], w[4]) + w[0]
238 end
239
240 threadsafe function ds2_bg(w,x) : FitFunc
241 Wave w
242 Variable x
243
244 //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
245 //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
246 //CurveFitDialog/ Equation:
247 //CurveFitDialog/ f(x) = w_0+( w_1*cos(pi*w_3/2+(1-w_3)*atan((x-w_2)/w_4)))/(((x-w_2)^2+w_4^2)^((1-w_3)/2)) +(w_5*cos(pi*w_7/2+(1-w_7)*atan((x-(w_6))/w_8)))/(((x-w_6)^2+w_8^2)^((1-w_7)/2))
248 //CurveFitDialog/ End of Equation
249 //CurveFitDialog/ Independent Variables 1
250 //CurveFitDialog/ x
251 //CurveFitDialog/ Coefficients 9
252 //CurveFitDialog/ w[0] = bg
253 //CurveFitDialog/ w[1] = amp1
254 //CurveFitDialog/ w[2] = pos1
255 //CurveFitDialog/ w[3] = sing1
256 //CurveFitDialog/ w[4] = wid1
257 //CurveFitDialog/ w[5] = amp2
258 //CurveFitDialog/ w[6] = pos2
259 //CurveFitDialog/ w[7] = sing2
260 //CurveFitDialog/ w[8] = wid2
261
262 variable ds1 = DoniachSunjic(x, w[1], w[2], w[3], w[4])
263 variable ds2 = DoniachSunjic(x, w[5], w[6], w[7], w[8])
264
265 return w[0] + ds1 + ds2
266 End
267
268 Function ds4_bg(w,x) : FitFunc
269 Wave w
270 Variable x
271
272 //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
273 //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
274 //CurveFitDialog/ Equation:
275 //CurveFitDialog/ f(x) = w_0+( w_1*cos(pi*w_3/2+(1-w_3)*atan((x-w_2)/w_4)))/(((x-w_2)^2+w_4^2)^((1-w_3)/2)) +(w_5*cos(pi*w_7/2+(1-w_7)*atan((x-(w_6))/w_8)))/(((x-w_6)^2+w_8^2)^((1-w_7)/2)) +( w_9*cos(pi*w_11/2+(1-w_11)*atan((x-w_10)/w_12)))/(((x-w_10)^2+w_12^2)^((1-w_11)/2)) +( w_13*cos(pi*w_15/2+(1-w_15)*atan((x-w_14)/w_16)))/(((x-w_14)^2+w_16^2)^((1-w_15)/2))
276 //CurveFitDialog/ End of Equation
277 //CurveFitDialog/ Independent Variables 1
278 //CurveFitDialog/ x
279 //CurveFitDialog/ Coefficients 17
280 //CurveFitDialog/ w[0] = w_0
281 //CurveFitDialog/ w[1] = w_11
282 //CurveFitDialog/ w[2] = w_12
283 //CurveFitDialog/ w[3] = w_13
284 //CurveFitDialog/ w[4] = w_14
285 //CurveFitDialog/ w[5] = w_21
286 //CurveFitDialog/ w[6] = w_22
287 //CurveFitDialog/ w[7] = w_23
288 //CurveFitDialog/ w[8] = w_24
289 //CurveFitDialog/ w[9] = w_31
290 //CurveFitDialog/ w[10] = w_32
291 //CurveFitDialog/ w[11] = w_33
292 //CurveFitDialog/ w[12] = w_34
293 //CurveFitDialog/ w[13] = w_41
294 //CurveFitDialog/ w[14] = w_42
295 //CurveFitDialog/ w[15] = w_43
296 //CurveFitDialog/ w[16] = w_44
297 Variable ds1, ds2, ds3, ds4
298 ds1=( w[1]*cos(pi*w[3]/2+(1-w[3])*atan((x-w[2])/w[4])))/(((x-w[2])^2+w[4]^2)^((1-w[3])/2))
299 ds2=( w[5]*cos(pi*w[7]/2+(1-w[7])*atan((x-w[6])/w[8])))/(((x-w[6])^2+w[8]^2)^((1-w[7])/2))
300 ds3=( w[9]*cos(pi*w[11]/2+(1-w[11])*atan((x-w[10])/w[12])))/(((x-w[10])^2+w[12]^2)^((1-w[11])/2))
301 ds4=( w[13]*cos(pi*w[15]/2+(1-w[15])*atan((x-w[14])/w[16])))/(((x-w[14])^2+w[16]^2)^((1-w[15])/2))
302
303
304 return w[0]+ds1+ds2+ds3+ds4
305
306
307 End
308
309 Function ds6_bg(w,x) : FitFunc
310 Wave w
311 Variable x
312
313 //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
314 //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
315 //CurveFitDialog/ Equation:
316 //CurveFitDialog/
317 //CurveFitDialog/ Variable g, ds1, ds2, ds3, ds4, ds5, ds6
318 //CurveFitDialog/ ds1=( w_11*cos(pi*w_13/2+(1-w_13)*atan((x-w_12)/w_14)))/(((x-w_12)^2+w_14^2)^((1-w_13)/2))
319 //CurveFitDialog/ ds2=( w_21*cos(pi*w_23/2+(1-w_23)*atan((x-w_22)/w_24)))/(((x-w_22)^2+w_24^2)^((1-w_23)/2))
320 //CurveFitDialog/ ds3=( w_31*cos(pi*w_33/2+(1-w_33)*atan((x-w_32)/w_34)))/(((x-w_32)^2+w_34^2)^((1-w_33)/2))
321 //CurveFitDialog/ ds4=( w_41*cos(pi*w_43/2+(1-w_43)*atan((x-w_42)/w_44)))/(((x-w_42)^2+w_44^2)^((1-w_43)/2))
322 //CurveFitDialog/ ds5=( w_51*cos(pi*w_53/2+(1-w_53)*atan((x-w_52)/w_54)))/(((x-w_52)^2+w_54^2)^((1-w_53)/2))
323 //CurveFitDialog/ ds6=( w_61*cos(pi*w_63/2+(1-w_63)*atan((x-w_62)/w_64)))/(((x-w_62)^2+w_64^2)^((1-w_63)/2))
324 //CurveFitDialog/
325 //CurveFitDialog/ f(x) =w_0+ds1+ds2+ds3+ds4+ds5+ds6
326 //CurveFitDialog/
327 //CurveFitDialog/ End of Equation
328 //CurveFitDialog/ Independent Variables 1
329 //CurveFitDialog/ x
330 //CurveFitDialog/ Coefficients 25
331 //CurveFitDialog/ w[0] = w_0
332 //CurveFitDialog/ w[1] = w_11
333 //CurveFitDialog/ w[2] = w_12
334 //CurveFitDialog/ w[3] = w_13
335 //CurveFitDialog/ w[4] = w_14
336 //CurveFitDialog/ w[5] = w_21
337 //CurveFitDialog/ w[6] = w_22
338 //CurveFitDialog/ w[7] = w_23
339 //CurveFitDialog/ w[8] = w_24
340 //CurveFitDialog/ w[9] = w_31
341 //CurveFitDialog/ w[10] = w_32
342 //CurveFitDialog/ w[11] = w_33
343 //CurveFitDialog/ w[12] = w_34
344 //CurveFitDialog/ w[13] = w_41
345 //CurveFitDialog/ w[14] = w_42
346 //CurveFitDialog/ w[15] = w_43
347 //CurveFitDialog/ w[16] = w_44
348 //CurveFitDialog/ w[17] = w_51
349 //CurveFitDialog/ w[18] = w_52
350 //CurveFitDialog/ w[19] = w_53
351 //CurveFitDialog/ w[20] = w_54
352 //CurveFitDialog/ w[21] = w_61
353 //CurveFitDialog/ w[22] = w_62
354 //CurveFitDialog/ w[23] = w_63
355 //CurveFitDialog/ w[24] = w_64
356
357
358 Variable ds1, ds2, ds3, ds4, ds5, ds6
359 ds1=( w[1]*cos(pi*w[3]/2+(1-w[3])*atan((x-w[2])/w[4])))/(((x-w[2])^2+w[4]^2)^((1-w[3])/2))
360 ds2=( w[5]*cos(pi*w[7]/2+(1-w[7])*atan((x-w[6])/w[8])))/(((x-w[6])^2+w[8]^2)^((1-w[7])/2))
361 ds3=( w[9]*cos(pi*w[11]/2+(1-w[11])*atan((x-w[10])/w[12])))/(((x-w[10])^2+w[12]^2)^((1-w[11])/2))
362 ds4=( w[13]*cos(pi*w[15]/2+(1-w[15])*atan((x-w[14])/w[16])))/(((x-w[14])^2+w[16]^2)^((1-w[15])/2))
363 ds5=( w[17]*cos(pi*w[19]/2+(1-w[19])*atan((x-w[18])/w[20])))/(((x-w[18])^2+w[20]^2)^((1-w[19])/2))
364 ds6=( w[21]*cos(pi*w[23]/2+(1-w[23])*atan((x-w[22])/w[24])))/(((x-w[22])^2+w[24]^2)^((1-w[23])/2))
365
366 return w[0]+ds1+ds2+ds3+ds4+ds5+ds6
367
368 End
369
370 structure DoniachSunjicStruct
371 // data structure for DoniachSunjicBroadS structural function fit
372
373 // waves populated by the FuncFit operation
374 wave pw
375 wave yw
376 wave xw
377
378 // convolution parameters to be set upon creation of the structure
379 variable precision
380 variable oversampling
381
382 // auxiliary fields used internally by DoniachSunjicBroadS
383 // do not touch these
384 wave xdw
385 wave model
386 wave broadening
387 wave convolution
388 EndStructure
389
390 //------------------------------------------------------------------------------
391 threadsafe function DoniachSunjicBroadS(s) : FitFunc
392 //------------------------------------------------------------------------------
393 // Two-peak (bulk + surface) Doniach-Sunjic line shape with Gaussian broadening (convolution).
394 // Hold parameter 5 at 0 to fit just one peak.
395
396 // Structural fit function for efficient fitting in procedures.
397 // Calculating the convolution requires auxiliary waves and additional, non-fitting parameters.
398 // To eliminate the time-consuming overhead of creating and killing the auxiliary waves,
399 // these waves are held in the fitting structure.
400
401 // Caution: The function on its own is thread-safe.
402 // However, since FuncFit uses the same structure in all threads, the fitting cannot run in parallel.
403 // Set /NTHR=1.
404
405 // See also Fit_DoniachSunjicBroad (example), DoniachSunjicBroad (conventional fit function)
406 Struct DoniachSunjicStruct &s
407
408 // pw[0] = bulk amplitude
409 // pw[1] = bulk position
410 // pw[2] = Lorentzian FWHM
411 // pw[3] = Donjach-Sunjic singularity index (0..1)
412 // pw[4] = surface shift
413 // pw[5] = surface/bulk ratio
414 // pw[6] = Gaussian FWHM
415 // pw[7] = constant background
416 // pw[8] = linear background
417
418 wave xw = s.xw
419 wave yw = s.yw
420 wave pw = s.pw
421
422 variable precision = s.precision
423 variable oversampling = s.oversampling
424
425 if (WaveExists(s.xdw))
426 wave xdw = s.xdw
427 wave model = s.model
428 wave broadening = s.broadening
429 wave convolution = s.convolution
430 else
431 make /n=0 /free xdw, model, broadening, convolution
432 redimension /d xdw, model, broadening, convolution
433 wave fs.xdw = xdw
434 wave fs.model = model
435 wave fs.broadening = broadening
436 wave fs.convolution = convolution
437 endif
438
439 // calculate wave spacing based on minimum spacing of desired x points
440 differentiate /p xw /d=xdw
441 xdw = abs(xdw)
442 variable xd = wavemin(xdw) / oversampling
443
444 // calculate broadening wave size based on width and precision variable
445 variable x0b = pw[6] * precision
446 variable nb = 2 * floor(x0b / xd) + 1
447
448 // calculate model size based on desired range for yw
449 variable x0m = max(abs(wavemax(xw) - pw[1]), abs(wavemin(xw) - pw[1])) + x0b
450 variable nm = 2 * floor(x0m / xd) + 1
451 nb = min(nb, nm * 10) // limit wave size to avoid runtime errors for unphysically large parameter
452
453 // create and calculate initial waves, normalize exponential
454 redimension /n=(nb) broadening
455 redimension /n=(nm) model
456 setscale/i x -x0b, x0b, "", broadening
457 setscale/i x -x0m, x0m, "", model
458
459 broadening = exp( - (x / pw[6])^2 * 4 * ln(2))
460 variable nrm = area(broadening)
461 broadening /= nrm
462 model = DoniachSunjic(x, 1, 0, pw[3], pw[2]) // bulk
463 model += DoniachSunjic(x, pw[5], pw[4], pw[3], pw[2]) // surface
464
465 // calculate the convolution
466 Convolve /a broadening, model
467 variable scale = pw[0] / wavemax(model)
468 model *= scale
469
470 // prepare output
471 nm = numpnts(model)
472 x0m = xd * (nm - 1) / 2
473 setscale/i x -x0m, x0m, "", model
474
475 yw = model(xw[p] - pw[1]) + pw[7] + pw[8] * xw[p]
476 yw = numtype(yw) ? 0 : yw
477 end
478
479 //------------------------------------------------------------------------------
480 function DoniachSunjicBroad(pw, yw, xw) : FitFunc
481 //------------------------------------------------------------------------------
482 // Two-peak (bulk + surface) Doniach-Sunjic line shape with Gaussian broadening (convolution).
483 // Hold parameter 5 at 0 to fit just one peak.
484 // Conventional fit function for use with the curve-fitting dialog.
485 // Compared to DoniachSunjicBroadS this function incurs extra overhead
486 // because auxiliary waves are created and killed between function calls.
487 // See also DoniachSunjicBroadS (optimized structural fit function)
488 Wave pw
489 Wave yw
490 Wave xw
491
492 // pw[0] = bulk amplitude
493 // pw[1] = bulk position
494 // pw[2] = Lorentzian FWHM
495 // pw[3] = Donjach-Sunjic singularity index (0..1)
496 // pw[4] = surface shift
497 // pw[5] = surface/bulk ratio
498 // pw[6] = Gaussian FWHM
499 // pw[7] = constant background
500 // pw[8] = linear background
501
502 // set up data structure
503 struct DoniachSunjicStruct fs
504 fs.precision = 5
505 fs.oversampling = 4
506
507 wave fs.pw = pw
508 wave fs.xw = xw
509 wave fs.yw = yw
510
511 // create temporary calculation waves in a global folder
512 dfref df = root:packages:pearl_fitfuncs:doniach_sunjic
513 if (DataFolderRefStatus(df) == 0)
514 newdatafolder root:packages:pearl_fitfuncs:doniach_sunjic
515 dfref df = root:packages:pearl_fitfuncs:doniach_sunjic
516 endif
517
518 wave /z /sdfr=df fs.xdw = xdw
519 wave /z /sdfr=df fs.model = model
520 wave /z /sdfr=df fs.broadening = broadening
521 wave /z /sdfr=df fs.convolution = convolution
522
523 if (WaveExists(fs.xdw) == 0)
524 dfref savedf = GetDataFolderDFR()
525 setdatafolder df
526 make /n=0 /d xdw, model, broadening, convolution
527 wave fs.xdw = xdw
528 wave fs.model = model
529 wave fs.broadening = broadening
530 wave fs.convolution = convolution
531 setdatafolder savedf
532 endif
533
534 // calculate
535 DoniachSunjicBroadS(fs)
536
537 yw = fs.yw
538 end
539
540 //------------------------------------------------------------------------------
541 function Calc_DoniachSunjicBroad(pw, yw)
542 //------------------------------------------------------------------------------
543 // Calculate the DoniachSunjicBroadS line shape
544 Wave pw // coefficient wave
545 Wave yw // output wave, correct x-scaling required on input
546
547 struct DoniachSunjicStruct fs
548 fs.precision = 5
549 fs.oversampling = 4
550
551 duplicate /free pw, fs.pw
552 duplicate /free yw, fs.xw
553 fs.xw = x
554 duplicate /free yw, fs.yw
555
556 DoniachSunjicBroadS(fs)
557
558 yw = fs.yw
559 end
560
561 //------------------------------------------------------------------------------
562 Function Fit_DoniachSunjicBroad(pw, yw, xw, ww)
563 //------------------------------------------------------------------------------
564 // Fit the DoniachSunjicBroadS line shape.
565 // The function applies constraints which assume that the energy scale is in eV.
566 // Returns chi^2.
567 wave pw // coefficient wave- pre-load it with initial guess
568 wave yw
569 wave /z xw
570 wave /z ww // weights (standard deviation)
571
572 struct DoniachSunjicStruct fs
573 fs.precision = 5
574 fs.oversampling = 4
575
576 duplicate /free pw, fs.pw
577 if (WaveExists(xw))
578 duplicate /free xw, fs.xw
579 else
580 duplicate /free yw, fs.xw
581 fs.xw = x
582 endif
583 duplicate /free yw, fs.yw
584
585 variable v_chisq = nan
586 variable V_FitMaxIters = 100
587 make /n=1 /t /free constraints = {"K0 >= 0", "K2 > 0", "K2 < 10", "K3 >= 0", "K3 < 1", "K4 >= -10", "K4 <= 10", "K5 >= 0", "K5 <= 1", "K6 >= 0", "K6 < 10"}
588 // note: only single thread allowed
589 FuncFit /NTHR=1 DoniachSunjicBroadS, pw, yw /X=xw /D /STRC=fs /C=constraints /NWOK /I=1 /W=ww
590
591 return v_chisq
592 End
593
594 //------------------------------------------------------------------------------
595 // peak-specific fit functions
596 //------------------------------------------------------------------------------
597
598 function Au4f(w, x): fitfunc
599 // fit function for a nitrogen 1s-pi* absorption spectrum
600 // modelled as multiple Voigt shapes on a constant background
601 // similar to the Igor VoigtFit function
602 // but with a constant gaussian width (instrumental broadening) for all peaks
603 // gaussian and lorentzian widths are specified as FWHM
604 wave w // parameters
605 // w[0] constant background
606 // w[1] linear background
607 // w[2] global gaussian FWHM
608 // w[3 + 0 + (n-1) * 3] peak n area
609 // w[3 + 1 + (n-1) * 3] peak n position
610 // w[3 + 2 + (n-1) * 3] peak n lorentzian FWHM
611 // length of wave defines number of peaks
612
613 // for compatibility with older code the linear background term can be omitted.
614 // if the number of parameters divides by 3, the linear background term is added,
615 // otherwise only the constant background.
616 variable x
617
618 variable np = numpnts(w)
619 variable ip, ip0
620
621 variable bg = w[0]
622 variable v = bg
623 if (mod(np, 3) == 0)
624 v += w[1] * x
625 ip0 = 3
626 else
627 ip0 = 2
628 endif
629
630 variable vc1, vc2, vc3, vc4
631 vc2 = 2 * sqrt(ln(2)) / w[ip0-1]
632 for (ip = ip0; ip < np; ip += 3)
633 vc1 = w[ip] / sqrt(pi) * vc2
634 vc3 = w[ip+1]
635 vc4 = vc2 * w[ip+2] / 2
636 v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
637 endfor
638
639 return v
640
641 end
642
643 function Au4f_2p2(w, x): fitfunc
644 // Au 4f 5/2 and 7/2 2-component Voigt fit with a common gaussian width
645 // gaussian and lorentzian widths are specified as FWHM
646 wave w // parameters
647 // w[0] constant background
648 // w[1] linear background
649 // w[2] global gaussian FWHM
650 // w[3] 5/2 bulk area
651 // w[4] 5/2 bulk position
652 // w[5] 5/2 lorentzian FWHM
653 // w[6] 7/2 bulk area
654 // w[7] 7/2 bulk position
655 // w[8] 7/2 lorentzian FWHM
656 // w[9] surface/bulk area ratio
657 // w[10] surface core level shift
658 variable x
659
660 variable bg = w[0] + w[1] * x
661 variable v = bg
662
663 variable vc1 // amplitude
664 variable vc2 // width
665 variable vc3 // position
666 variable vc4 // shape
667 vc2 = 2 * sqrt(ln(2)) / w[2]
668
669 // 5/2 bulk
670 vc1 = w[3] / sqrt(pi) * vc2
671 vc3 = w[4]
672 vc4 = vc2 * w[5] / 2
673 v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
674
675 // 5/2 surface
676 vc1 = w[3] / sqrt(pi) * vc2 * w[9]
677 vc3 = w[4] + w[10]
678 vc4 = vc2 * w[5] / 2
679 v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
680
681 // 7/2 bulk
682 vc1 = w[6] / sqrt(pi) * vc2
683 vc3 = w[7]
684 vc4 = vc2 * w[8] / 2
685 v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
686
687 // 7/2 surface
688 vc1 = w[6] / sqrt(pi) * vc2 * w[9]
689 vc3 = w[7] + w[10]
690 vc4 = vc2 * w[8] / 2
691 v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
692
693 return v
694
695 end
696
697 function ShowComponents_Au4f_2p2(coef_wave, fit_wave)
698 wave coef_wave
699 wave fit_wave
700
701 duplicate /free coef_wave, coef1, coef2
702 coef1[9] = 0
703 coef2[3] *= coef_wave[9]
704 coef2[4] += coef_wave[10]
705 coef2[6] *= coef_wave[9]
706 coef2[7] += coef_wave[10]
707 coef2[9] = 0
708
709 string s_fit_wave = NameOfWave(fit_wave)
710 string s_fit_p1 = s_fit_wave + "_p1"
711 string s_fit_p2 = s_fit_wave + "_p2"
712 duplicate /o fit_wave, $(s_fit_p1) /wave=fit_p1
713 duplicate /o fit_wave, $(s_fit_p2) /wave=fit_p2
714
715 fit_p1 = Au4f_2p2(coef1, x)
716 fit_p2 = Au4f_2p2(coef2, x)
717
718 string traces = TraceNameList("", ";", 1)
719 if ((WhichListItem(s_fit_wave, traces, ";") >= 0) && (WhichListItem(s_fit_p1, traces, ";") < 0))
720 appendtograph fit_p1, fit_p2
721 ModifyGraph lstyle($s_fit_p1)=2
722 ModifyGraph lstyle($s_fit_p2)=2
723 ModifyGraph rgb($s_fit_p1)=(0,0,65280)
724 ModifyGraph rgb($s_fit_p2)=(0,0,65280)
725 endif
726 end
727
728 function Au4f_2p3(w, x): fitfunc
729 // Au 4f 5/2 and 7/2 3-component Voigt fit with a common gaussian width
730 // gaussian and lorentzian widths are specified as FWHM
731 wave w // parameters
732 // w[0] constant background
733 // w[1] linear background
734 // w[2] global gaussian FWHM
735 // w[3] 5/2 bulk area
736 // w[4] 5/2 bulk position
737 // w[5] 5/2 lorentzian FWHM
738 // w[6] 7/2 bulk area
739 // w[7] 7/2 bulk position
740 // w[8] 7/2 lorentzian FWHM
741 // w[9] surface/bulk area ratio
742 // w[10] surface core level shift
743 // w[11] 2nd layer/bulk area ratio
744 // w[12] 2nd layer core level shift
745 variable x
746
747 variable bg = w[0] + w[1] * x
748 variable v = bg
749
750 variable vc1 // amplitude
751 variable vc2 // width
752 variable vc3 // position
753 variable vc4 // shape
754 vc2 = 2 * sqrt(ln(2)) / w[2]
755
756 // 5/2 bulk
757 vc1 = w[3] / sqrt(pi) * vc2
758 vc3 = w[4]
759 vc4 = vc2 * w[5] / 2
760 v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
761
762 // 5/2 surface
763 vc1 = w[3] / sqrt(pi) * vc2 * w[9]
764 vc3 = w[4] + w[10]
765 vc4 = vc2 * w[5] / 2
766 v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
767
768 // 5/2 2nd layer
769 vc1 = w[3] / sqrt(pi) * vc2 * w[11]
770 vc3 = w[4] + w[12]
771 vc4 = vc2 * w[5] / 2
772 v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
773
774 // 7/2 bulk
775 vc1 = w[6] / sqrt(pi) * vc2
776 vc3 = w[7]
777 vc4 = vc2 * w[8] / 2
778 v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
779
780 // 7/2 surface
781 vc1 = w[6] / sqrt(pi) * vc2 * w[9]
782 vc3 = w[7] + w[10]
783 vc4 = vc2 * w[8] / 2
784 v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
785
786 // 7/2 2nd layer
787 vc1 = w[6] / sqrt(pi) * vc2 * w[11]
788 vc3 = w[7] + w[12]
789 vc4 = vc2 * w[8] / 2
790 v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
791
792 return v
793
794 end
795
796 function ShowComponents_Au4f_2p3(coef_wave, fit_wave)
797 wave coef_wave
798 wave fit_wave
799
800 duplicate /free coef_wave, coef1, coef2, coef3
801 coef1[9] = 0
802 coef1[11] = 0
803
804 coef2[3] *= coef_wave[9]
805 coef2[4] += coef_wave[10]
806 coef2[6] *= coef_wave[9]
807 coef2[7] += coef_wave[10]
808 coef2[9] = 0
809 coef2[11] = 0
810
811 coef3[3] *= coef_wave[11]
812 coef3[4] += coef_wave[12]
813 coef3[6] *= coef_wave[11]
814 coef3[7] += coef_wave[12]
815 coef3[9] = 0
816 coef3[11] = 0
817
818 string s_fit_wave = NameOfWave(fit_wave)
819 string s_fit_p1 = s_fit_wave + "_p1"
820 string s_fit_p2 = s_fit_wave + "_p2"
821 string s_fit_p3 = s_fit_wave + "_p3"
822 duplicate /o fit_wave, $(s_fit_p1) /wave=fit_p1
823 duplicate /o fit_wave, $(s_fit_p2) /wave=fit_p2
824 duplicate /o fit_wave, $(s_fit_p3) /wave=fit_p3
825
826 fit_p1 = Au4f_2p2(coef1, x)
827 fit_p2 = Au4f_2p2(coef2, x)
828 fit_p3 = Au4f_2p2(coef3, x)
829
830 string traces = TraceNameList("", ";", 1)
831 if ((WhichListItem(s_fit_wave, traces, ";") >= 0) && (WhichListItem(s_fit_p1, traces, ";") < 0))
832 appendtograph fit_p1, fit_p2, fit_p3
833 ModifyGraph lstyle($s_fit_p1)=2
834 ModifyGraph lstyle($s_fit_p2)=2
835 ModifyGraph lstyle($s_fit_p3)=2
836 ModifyGraph rgb($s_fit_p1)=(0,0,65280)
837 ModifyGraph rgb($s_fit_p2)=(0,0,65280)
838 ModifyGraph rgb($s_fit_p3)=(0,0,65280)
839 endif
840 end
841
851 function FermiGaussConv(pw, yw, xw) : FitFunc
852 WAVE pw, yw, xw
853
854 // half width of temporary gaussian wave is pw[5] multiplied by this factor (may be fractional)
855 variable precision_g = 5
856 variable oversampling = 4
857
858 // calculate wave spacing based on minimum spacing of desired x points
859 duplicate /free xw, xdw
860 differentiate /p xw /d=xdw
861 xdw = abs(xdw)
862 variable xd = wavemin(xdw) / oversampling
863
864 // calculate gausswave size based on pw[5] and precision variable
865 variable x0g = abs(pw[5]) * precision_g
866 variable ng = 2 * floor(x0g / xd) + 1
867
868 // calculate fermiwave size based on desired range for yw
869 variable emax = wavemax(xw)
870 variable emin = wavemin(xw)
871 variable x0f = max(abs(emax - pw[3]), abs(emin - pw[3])) + x0g
872 variable ne = 2 * floor(x0f / xd) + 1
873
874 // create and calculate initial waves, normalize exponential
875 make /d /n=(ng) /free gausswave
876 make /d /n=(ne) /free fermiwave
877 setscale/i x -x0g, x0g, "", gausswave
878 setscale/i x -x0f, x0f, "", fermiwave
879
880 gausswave = exp( - (x / pw[5] )^2 )
881 fermiwave = 1 / (exp( x / (kBoltzmann * pw[4])) + 1.0 )
882
883 // calculate the convolution
884 duplicate /free fermiwave, resultwave
885 Convolve /a gausswave, resultwave
886 variable rmax = wavemax(resultwave)
887 resultwave /= rmax
888
889 // prepare output
890 ng = numpnts(resultwave)
891 x0g = xd * (ng - 1) / 2
892 setscale/i x -x0g, x0g, "", resultwave
893
894 yw = pw[2] * resultwave(xw[p] - pw[3]) + pw[0] + pw[1] * xw[p]
895 end
896
897
901 function ShirleyBG(w, bg, p1, p2)
902 wave w
903 wave bg
904 variable p1, p2
905
906 duplicate /o w, bg
907 integrate /meth=1 w /d=bg
908
909 variable bg1 = bg[p1]
910 variable bg2 = bg[p2]
911 bg -= bg1
912 bg /= bg2 - bg1
913 bg *= w[p2] - w[p1]
914 bg += w[p1]
915 end
MultiGaussLinBG
threadsafe variable MultiGaussLinBG(wave w, variable x)
multiple gaussian peaks on a linear background fit function.
Definition: pearl-fitfuncs.ipf:44
DoubletGaussLinBG_AO
threadsafe variable DoubletGaussLinBG_AO(wave pw, wave yw, wave xw)
doublet gaussian peaks on a linear background fit function (all at once).
Definition: pearl-fitfuncs.ipf:117
DoniachSunjicBroad
variable DoniachSunjicBroad(wave pw, wave yw, wave xw)
Definition: pearl-fitfuncs.ipf:480
MultiGaussLinBG_AO
threadsafe variable MultiGaussLinBG_AO(wave pw, wave yw, wave xw)
multiple gaussian peaks on a linear background fit function (all at once).
Definition: pearl-fitfuncs.ipf:79
ds4_bg
variable ds4_bg(wave w, variable x)
Definition: pearl-fitfuncs.ipf:268
DoniachSunjicStruct
Definition: pearl-fitfuncs.ipf:370
FermiGaussConv
variable FermiGaussConv(wave pw, wave yw, wave xw)
convolution of Fermi-Dirac distribution and a Gaussian.
Definition: pearl-fitfuncs.ipf:851
DoniachSunjicBroadS
threadsafe variable DoniachSunjicBroadS(DoniachSunjicStruct *s)
Definition: pearl-fitfuncs.ipf:391
DoniachSunjic
threadsafe variable DoniachSunjic(variable x, variable amp, variable pos, variable sing, variable fwhm)
Doniach-Sunjic line shape.
Definition: pearl-fitfuncs.ipf:174
Au4f
variable Au4f(wave w, variable x)
Definition: pearl-fitfuncs.ipf:598
Au4f_2p3
variable Au4f_2p3(wave w, variable x)
Definition: pearl-fitfuncs.ipf:728
Au4f_2p2
variable Au4f_2p2(wave w, variable x)
Definition: pearl-fitfuncs.ipf:643
ShowComponents_Au4f_2p2
variable ShowComponents_Au4f_2p2(wave coef_wave, wave fit_wave)
Definition: pearl-fitfuncs.ipf:697
Calc_DoniachSunjicBroad
variable Calc_DoniachSunjicBroad(wave pw, wave yw)
Definition: pearl-fitfuncs.ipf:541
ShowComponents_Au4f_2p3
variable ShowComponents_Au4f_2p3(wave coef_wave, wave fit_wave)
Definition: pearl-fitfuncs.ipf:796
Fit_DoniachSunjicBroad
variable Fit_DoniachSunjicBroad(wave pw, wave yw, wave xw, wave ww)
Definition: pearl-fitfuncs.ipf:562
ds2_bg
threadsafe variable ds2_bg(wave w, variable x)
Definition: pearl-fitfuncs.ipf:240
ds6_bg
variable ds6_bg(wave w, variable x)
Definition: pearl-fitfuncs.ipf:309
ShirleyBG
variable ShirleyBG(wave w, wave bg, variable p1, variable p2)
calculate the shirley background
Definition: pearl-fitfuncs.ipf:901
MultiDoniachSunjicLinBG
variable MultiDoniachSunjicLinBG(wave w, variable x)
multiple doniach-sunjic peaks on a linear background fit function.
Definition: pearl-fitfuncs.ipf:201
ds1_bg
threadsafe variable ds1_bg(wave w, variable x)
Definition: pearl-fitfuncs.ipf:217
MultiVoigtLinBG
variable MultiVoigtLinBG(wave w, variable x)
multiple voigt peaks on a linear background fit function.
Definition: pearl-fitfuncs.ipf:144