This commit is contained in:
2019-03-20 13:52:00 +01:00
parent 3084fe0510
commit 5db0f78aee
910 changed files with 191152 additions and 322 deletions

View File

@@ -0,0 +1,47 @@
Take a six circle diffractometer with angles:
delta, nu, mu, eta, chi, phi
and virtual angles:
qaz, naz, psi, alpha, beta.
Many combinations of these can be constrained:
constrain
>>> con nu
>>> con psi
>>> con mu
>>> con nu mu a_eq_b
real angles are always constrained to there last set position. If they are too far from here
an error will result.
>>> pos nu 0 (moves, parameter tracks last set value (actually checks it when hkl moved))
>>> pos psi 90 (does not move, sets parameter in diffcalc)
>>> pos mu 0 (moves)
>>> pos hkl [1 0 0] (moves based on last set nu, psi, mu)
>>> pos betain --> Exception, not constrained
moving a virtual angle simply sets it to efftec the next hkl move
Here we need onlu con, uncon and pos.
......
However it would be nice to be able to pos betain for example and have it change
betain while staying on the same reflection. This might be enabled by locking the
the current hkl position. It would be trick to make this work with the physical angles though.
>>> lock hkl
>>> pos psi 90 (moves immediately)
>>> scan psi 0 90 1 (scans, moving immediately)
>>> pos mu 0 (does not move immediately) (could work by listening to target positions, and triggering move when complete)
>>> pos c(mu) moves
>>> pos mu_c moves
Only one thing would be varyable at a time unless they are put in a CoordinatedMotionGroup,
which would be hard for the real motors)

View File

@@ -0,0 +1,525 @@
/* [wxMaxima batch file version 1] [ DO NOT EDIT BY HAND! ]*/
/* [ Created with wxMaxima version 11.08.0 ] */
/* [wxMaxima: input start ] */
Rx:matrix([1,0,0],[0, cos(theta), -sin(theta)],[0, sin(theta), cos(theta)])$
Ry:matrix([cos(theta), 0, sin(theta)], [0, 1, 0], [-sin(theta), 0, cos(theta)])$
Rz:matrix([cos(theta), -sin(theta), 0], [sin(theta), cos(theta), 0], [0, 0, 1])$
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Equation 5:
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
PHI:subst(-phi, theta, Rz);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
CHI:subst(chi, theta, Ry);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
ETA:subst(-eta, theta, Rz);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
MU:subst(mu, theta, Rx);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Generic V:
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
V:matrix([v11, v12, v13], [v21, v22, v23], [v31, v32, v33]);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
[wxMaxima: comment end ] */
/* [wxMaxima: section start ]
When one sample-orienting angle is given
[wxMaxima: section end ] */
/* [wxMaxima: subsect start ]
For mu fixed
[wxMaxima: subsect end ] */
/* [wxMaxima: input start ] */
eq34:ETA.CHI.PHI;
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
eq34_chi0:subst(0, chi, eq34);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
*phi* with chi <> 0
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
trigreduce(trigsimp((eq34[3,2]=V[3,2])/(eq34[3,1]=V[3,1])));
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
show that with phi with v31 == 0 and v12 <> 0, no special case is needed when using atan2
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
solve(cos(phi)=0, phi);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
atan2(1234,0);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
show that with phi with v32 == 0 and v31 <> 0, no special case is needed when using atan2
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
solve(sin(phi)=0, phi);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
atan2(0,1234);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
*eta* with chi <> 0
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
trigreduce(trigsimp((-eq34[2,3]=V[2,3]) / (eq34[1, 3]=V[1,3])));
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
eta with v23 == 0 and v13 == 0 (phi||eta degeneracy because chi == 0)
Then see equation for phi+eta above
[wxMaxima: comment end ] */
/* [wxMaxima: comment start ]
*chi*
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
trigsimp(sqrt((eq34[3,1]=V[3,1])^2+(eq34[3,2]=V[3,2])^2)/(eq34[3,3]=V[3,3]));
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
*phi + eta* with chi == 0
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
trigreduce(trigrat((eq34_chi0[1,2]=V[1,2])/(eq1:eq34_chi0[1,1]=V[1,1])));
/* [wxMaxima: input end ] */
/* [wxMaxima: subsect start ]
For phi fixed
[wxMaxima: subsect end ] */
/* [wxMaxima: input start ] */
eq36:MU.ETA.CHI;
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
eq36_eta90:subst(%pi/2, eta, eq36);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
*eta*
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
trigsimp((eq36[1,2]=V[1,2])/sqrt((eq36[2,2]=V[2,2])^2+(eq36[3,2]=V[3,2])^2));
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
*mu* with eta <> +-90
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
trigreduce(trigsimp((eq36[3,2]=V[3,2])/(eq36[2,2]=V[2,2])));
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
*chi* with eta <> +-90
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
trigreduce(trigsimp((eq36[1,3]=V[1,3])/(eq36[1,1]=V[1,1])));
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
*chi + mu* with eta == +-90
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
trigreduce(trigrat((eq36_eta90[2,3]=V[2,3])/(eq36_eta90[2,1]=V[2,1])));
/* [wxMaxima: input end ] */
/* [wxMaxima: subsect start ]
For eta or chi fixed
[wxMaxima: subsect end ] */
/* [wxMaxima: input start ] */
eq38:MU.ETA.CHI.PHI;
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
*chi* (eq. 39) given eta, and eta <> +-90 (with eta == +-90 chi||mu)
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
(eq38[1,3]=V[1,3])/cos(eta);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
[wxMaxima: comment end ] */
/* [wxMaxima: comment start ]
*eta* given chi, and chi <> 0 (with chi == 0 phi||eta)
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
(eq38[1,3]=V[1,3])/sin(chi);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
*mu* given that chi and eta have been given or calclulated respecitively
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
top:(eq38[3,3]=V[3,3])*sin(eta)*sin(chi) + (eq38[2,3]=V[2,3])*cos(chi);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
bot:-(eq38[3,3]=V[3,3])*cos(chi)+(eq38[2,3]=V[2,3])*sin(eta)*sin(chi);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
factor(top);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
factor(bot);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
trigsimp(top/bot);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
*phi - mu* when phi || mu because chi == +-90, eta == 0 or eta == 180
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
phi_mu_parallel:subst(0, eta, subst(%pi/2, chi, eq38));
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
trigreduce(trigrat((phi_mu_parallel[2,1]=V[2,1])/(phi_mu_parallel[2,2]=V[2,2])));
/* [wxMaxima: input end ] */
/* [wxMaxima: section start ]
Two sample angles given
[wxMaxima: section end ] */
/* [wxMaxima: input start ] */
THETA:subst(-theta, theta, Rz);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
PSI:subst(psi, theta, Rx);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
F:subst(xi, theta, Ry);
/* [wxMaxima: input end ] */
/* [wxMaxima: section start ]
psi, mu, eta given
[wxMaxima: section end ] */
/* [wxMaxima: input start ] */
eq49:transpose(PHI).transpose(CHI).transpose(ETA).transpose(MU).F;
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
*chi*
[wxMaxima: comment end ] */
/* [wxMaxima: comment start ]
using the linear combination identity
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
comb_idenity:sqrt(A^2+B^2)*sin(x+omega);
omega:atan(B/A);
A*sin(x)+B*cos(x)=comb_idenity;
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
a:-sin(eta)*cos(mu)$
b:-sin(mu)$
V32=a*sin(chi)+b*cos(chi);
V32=subst(b, B, subst(a, A, comb_idenity));
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
asin(%/(sqrt(sin(mu)^2+sin(eta)^2*cos(mu)^2))), triginverses=all;
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
*xi and phi*
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
top:factor(eq49[3,1]*cos(xi)+eq49[3,3]*sin(xi));
bot:factor(eq49[3,1]*sin(xi)-eq49[3,3]*cos(xi));
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
factor(top/bot);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
When mu=-90 and eta = 0, used to for a surface normal vertical mode
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
eq49_vert:subst(-%pi/2, mu, subst(0, eta, eq49));
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
(eq49_vert[2,2]=V[2,2]) / (eq49_vert[1,2]=V[1,2]);
/* [wxMaxima: input end ] */
/* [wxMaxima: subsect start ]
mu, phi, qaz (for three circle on i10 and i06, not in paper )
[wxMaxima: subsect end ] */
/* [wxMaxima: input start ] */
thisV:transpose(MU).F.THETA;
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
Nphi:matrix([n11, n12, n13], [n21, n22, n23], [n31, n32, n33]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
eq:ETA.CHI.PHI.Nphi.transpose(PSI);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
*chi*
[wxMaxima: comment end ] */
/* [wxMaxima: comment start ]
using the linear combination identity
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
comb_idenity:sqrt(A^2+B^2)*sin(x+omega);
omega:atan(B/A);
A*sin(x)+B*cos(x)=comb_idenity;
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
on V31:
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
a:-1*(n21*sin(phi)+n11*cos(phi))$
b:n31$
V31=a*sin(chi)+b*cos(chi);
V31=subst(b, B, subst(a, A, comb_idenity));
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
asin(%/sqrt((-n21*sin(phi)-n11*cos(phi))^2+n31^2)), triginverses=all;
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
*xi and phi*
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
top:factor(eq49[3,1]*cos(xi)+eq49[3,3]*sin(xi));
bot:factor(eq49[3,1]*sin(xi)-eq49[3,3]*cos(xi));
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
factor(top/bot);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
solve();
/* [wxMaxima: input end ] */
/* [wxMaxima: section start ]
Fixed mu, chi, psi (probably with mu=chi=0) (not in paper)
[wxMaxima: section end ] */
/* [wxMaxima: input start ] */
Vcalulated:Nphi.transpose(PSI).transpose(THETA);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
thisV:transpose(PHI).transpose(CHI).transpose(ETA).transpose(MU).F;
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
v:thisVvert:subst(0, chi, subst(0, mu, thisV));
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
acos(thisVvert[3,3]=V[3,3]), triginverses=all;
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
top:(v[1,2]=V[1,2])*cos(phi) + (v[2,2]=V[2,2])*sin(phi);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
bot:(v[1,2]=V[1,2])*sin(phi) - (v[2,2]=V[2,2])*cos(phi);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
factor(top);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
factor(bot);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
trigsimp(top/bot);
/* [wxMaxima: input end ] */
/* [wxMaxima: title start ]
5.5 subset with eta=chi=0 & phi set
[wxMaxima: title end ] */
/* [wxMaxima: input start ] */
matrix([cos(theta)*sin(qaz)], [-sin(theta)], [cos(theta)*cos(qaz)]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
h_phi:matrix([h1], [h2], [h3]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
Z:MU.ETA.CHI.PHI;
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
eq68yterm:-sin(theta) = ((Z.h_phi))[2][1];
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
expands(%);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
eq68_chi_eta_0:subst(0, chi, subst(0, eta, Z.h_phi));
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
eq68_chi_eta_0_yterm:-sin(theta)=eq68_chi_eta_0[2];
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
subst(0, chi, subst(0, eta, eq68yterm));
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
a;
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
ratsubst(a, -h3, eq68_chi_eta_0_yterm);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
a:-h3;
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
b:-h1*sin(phi) +h2*cos(phi);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
c:-sin(theta);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
ratsubst(cc, c, ratsubst(bb, b, ratsubst(aa, a, eq68_chi_eta_0_yterm)));
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
arcsin(c/sqrt(a^2+b^2)) - arctan(b, a);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
eq68_chi_eta_0[1] /eq68_chi_eta_0[2];
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
without chi=eta=0
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
eq68yterm:-sin(theta) = ((Z.h_phi))[2][1];
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
expand(eq68yterm);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
solve for mu unknown
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
c:-sin(theta);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
a:sin(chi)*h2*sin(phi) + sin(chi)*h1*cos(phi) - cos(chi)*h3;
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
b: -cos(chi)*sin(eta)*h2*sin(phi) -cos(eta)*h1*sin(phi) +cos(eta)*h2*cos(phi) -cos(chi)*sin(eta)*h1*cos(phi) - sin(chi)*sin(eta)*h3;
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
expand(subst(a, aa, subst(b, bb, -sin(theta)=aa*sin(mu) + bb*cos(mu))));
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Check a and b expand to produce original (Okay)
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
expand(eq68yterm);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Check against special case above (Okay)
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
subst(0, chi, subst(0, eta, a));
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
subst(0, chi, subst(0, eta, b));
/* [wxMaxima: input end ] */
/* Maxima can't load/batch files which end with a comment! */
"Created with wxMaxima"$

View File

@@ -0,0 +1,71 @@
Creating a UB Matrix
There are three euler modes:
=bisecting: eta and delta are fixed, phi and chi are not fixed.
=fixed phi: phi and 2theta are fixed, eta and chi are not fixed.
=fixed psi: Not used for creating a UB matrix .
First creat a reflection file to store the reflections data using:
reffile('name')
Set the crystal lattice:
latt([a]) assumes cubic
latt([a,b]) assumes tetragonal
latt([a,b,c]) assumes orthorhombic
latt([a,b,c,gam]) assumes monclinic/hexagonal gam different from 90.
latt([a,b,c,alp,bet,gam])
Use:
c2th([h k l])
to calculate the 2 theta position for the hkl for example:
c2th([0 0 2])
Then use the following to move the diffractometer to the correct positions:
pos delta c2th([0 0 2]) eta c2th([0 0 2])/2
You can now scan eta, chi, and delta to optomise the peak intensity using the following scans for example:
scancn eta 0.01 40 w 0.2 t 1
scancn chi 0.01 40 w 0.2 t 1
scancn delta 0.01 40 w 0.2 t 1
A few iterations may be required.
Now that you have the first reflection it can be stored using the following command:
saveref('reflable',[h k l])
saveref('Ti1',[0 0 2]) for the above example.
Then create a dummy UB matrix using a dummy non-parallel hkl plane eg:
ubm('Ti1',[2 0 0])
Useing the following command to calculate the direction of the second reflection:
hkl_calc([0 2 2])
If the calculated positions can be safely achieved then type:
pos hkl [0 2 2]
Find the second reflection by scanning phi, once the reflection is found save the second reflection using:
saveref('Ti2',[0 2 2]) for example.
Now create a real UB-Matrix using:
ubm('Ti1','Ti2')
You can now drive in recriprocal space.
To change the lattice parameters according the found Bragg peaks
latt([latt()[0]*2/l()]) (cubic only)