I do X-ray diffraction experiments, and I'm trying to fit my experimental data to determine the best-fit values of lattice parameters "a", "b", and "c". The complication is that the dependent variable, "q", depend on the lattice parameters as well as the Miller lattice indices, "h", "k", and "l". However, there are a finite number of allowed values for each set of h, k, and l. The idea below is that I pass 4 experimentally observed dependent variables, and Igor tries all 715 (a "13 choose 4" problem) combinations of 4 sets of h, k, and l from the 13 I hard-coded. It does that fine. I'm having trouble, though, with fitting each a, b, and c during each iteration to the observed peaks. I thought I could use the all-at-once fitting function, but it appears that it does not accept non-waveform X data. I would much appreciate any thoughts on a work-around, an alternative solution, or a way to pass the X data I generate in the for-loops (the Miller lattice index sets) to the fitting function. Apologies if this is unclear; I'd be happy to provide additional details.
Function O70LatPar(q_expt)
Wave q_expt // pass a wave of experimental data
Variable i = 0, j = 0, m = 0, n = 0
Variable index = 1
Variable V_FitError = 4 // suppress progress window
Make/O h = {1,0,0,1,1,1,0,1,2,2,2,0,1} // h, k, and l give 13 allowed reflection planes for orthorhombic lattice
Make/O k = {1,2,0,1,3,1,4,3,0,2,2,4,3}
Make/O l = {1,2,4,3,1,5,0,3,2,0,2,4,5}
Make/O/D latpar = {30,40,70} // lattice parameters--a, b, and c--of unit cell; must find "best fit" values
For (i=0; i<13; i+=1) // for loops solve "13 choose 4" combination problem; that is, all 715 unique combinations of lattice index sets are tried in the fit function
For (j=0; j
In the main function O70LatPar(), you compute a wave "latind". In the function "fitting" you have used the name "latind" in the position of the independent variable wave.
In the fit function, the independent variable wave contains the X values corresponding to the Y values passed in the FuncFit command in the position in the command where you have q_expt. Since your FuncFit command has no /X flag, the independent variable (or X values) come from the wave scaling of q_expt. But you can associate a separate wave of X values using the /X flag:
The X wave must have the same number of points as the Y wave, so in this case, myXwave must have the same number of points as q_expt.
I feel like I haven't answered your question, though. Perhaps try again with some more details in your explanation.
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
January 27, 2012 at 09:06 am - Permalink
The wave "latind" is actually a matrix at the moment. It comprises 4 sets of h, k, and l. Think of it as vectors X0 through X3 (e.g., X0 = {h0, k0, l0}). So, I'm actually passing 12 points to "fitting", and "q_expt" has only 4 points.
Here's how I've approached the problem manually in Excel (I attached a screenshot):
I know what values of h, k, and l are allowed by nature. I make a (hopefully) good guess as to which observed peaks (i.e., values of q_expt) correspond to certain sets of h, k, and l. I then run a simple sum-of-squared errors analysis to calculate the values of a, b, and c. I then manually switch which observed q values go with which sets of h, k, and l and repeat the analysis. I'm attempting to automate this process in Igor.
Is there a direct analogue to Excel's solver functionality in Igor? My original intention was to write a simple function (sum of (q_theo - q_expt)^2) and use Optimize to find the minimum, but it appears you can't vary parameters this way.
Any additional input will of course be appreciated. At this point, I either need a way to send my h, k, l matrix to my current all-at-once fitting function, a way to automate Excel's solver functionality, or a way to split up the problem so I can use FuncFit.
January 27, 2012 at 02:06 pm - Permalink
But it sounds like you need to fit a solution for a, b, and c for each of several sets of h, k, l. So you need to do several fits, and you need to pass in values of hkl that will be treated as constants in any given fit.
The easiest way to pass in constants is to add them to the coefficient wave. So in your case, you would have a six-point coefficient wave with a, b, c, h, k, l. Since h, k, l are constants, you would pre-set them to the appropriate values and hold them during the fit.
A somewhat cleaner way to do it would be to use a structure fit function and pass the values of h, k, l as additional members of the structure. This eliminates the possibly error-prone requirement of holding the coefficients that correspond to h,k,l.
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
January 30, 2012 at 04:34 pm - Permalink