Commit 939a20c7 authored by Tobias WEBER's avatar Tobias WEBER

tas calculations

parent 1af8d689
......@@ -15,7 +15,7 @@
\begin{document}
Collection of useful formulas, T. Weber, July 13, 2018.
Useful formulas, T. Weber, tweber@ill.fr, July 13, 2018.
\section{Scattering Triangle}
......@@ -30,7 +30,9 @@ Collection of useful formulas, T. Weber, July 13, 2018.
\begin{equation} \left< Q | Q \right> = \left( \left< k_i \right| - \left< k_f \right| \right) \cdot \left( \left| k_i \right> - \left| k_f \right> \right) \end{equation}
\begin{equation} \left< Q | Q \right> = \left< k_i | k_i \right> + \left< k_f | k_f \right> - 2 \left< k_i | k_f \right> \end{equation}
\begin{equation} Q^2 = k_i^2 + k_f^2 - 2 k_i k_f \cos a_4 \end{equation}
\begin{equation} \boxed{ a_4 = \arccos \left( \frac{k_i^2 + k_f^2 - Q^2}{2 k_i k_f} \right) } \end{equation}
\begin{equation} \boxed{ a_4 = \sigma_s \cdot \arccos \left( \frac{k_i^2 + k_f^2 - Q^2}{2 k_i k_f} \right) } \end{equation}
The sign of $a_4$ is given by the sample scattering sense $\sigma_s = \pm 1$.
......@@ -38,18 +40,26 @@ Collection of useful formulas, T. Weber, July 13, 2018.
\begin{equation} \boxed{ a_3 = 180^{\circ} - \left( \psi + \xi \right) } \end{equation}
\subsubsection*{Angle $\psi$}
Angle $\psi$ between $\left| k_i \right>$ and $\left| Q \right>$, in units of \AA{}$^{-1}$, as before:
\begin{equation} \left| k_f \right> = \left| k_i \right> - \left| Q \right> \end{equation}
\begin{equation} \left< k_f | k_f \right> = \left( \left< k_i \right| - \left< Q \right| \right) \cdot \left( \left| k_i \right> - \left| Q \right> \right) \end{equation}
\begin{equation} \left< k_f | k_f \right> = \left< k_i | k_i \right> + \left< Q | Q \right> - 2 \left< k_i | Q \right> \end{equation}
\begin{equation} k_f^2 = k_i^2 + Q^2 - 2 k_i Q \cos \psi \end{equation}
\begin{equation} \boxed{ \psi = \arccos \left( \frac{k_i^2 + Q^2 - k_f^2}{2 k_i Q} \right) } \end{equation}
\begin{equation} \boxed{ \psi = \sigma_s \cdot \arccos \left( \frac{k_i^2 + Q^2 - k_f^2}{2 k_i Q} \right) } \end{equation}
\subsubsection*{Angle $\xi$}
Angle $\xi$ between $\left| Q \right>$ and orientation vector $\left| a \right>$ (i.e. $ax$, $ay$, $az$), in units of rlu; $g_{ij} = \left| b_i \left> \right< b_j \right|$ is the covariant metric of the reciprocal lattice with basis $\left| b_i \right>$:
\begin{equation} \xi = \arccos \left( \frac{ \left< Q | a \right> }{ \sqrt{\left< Q | Q \right>} \sqrt{\left< a | a \right>} } \right) \end{equation}
\begin{equation} \boxed{ \xi = \arccos \left( \frac{ Q^i g_{ij} a^j }{ \sqrt{Q^i g_{ij} Q^j} \sqrt{a^i g_{ij} a^j} } \right) } \end{equation}
\begin{equation} \xi = \sigma_{\mathrm{side}} \cdot \arccos \left( \frac{ \left< Q | a \right> }{ \sqrt{\left< Q | Q \right>} \sqrt{\left< a | a \right>} } \right) \end{equation}
\begin{equation} \boxed{ \xi = \sigma_{\mathrm{side}} \cdot \arccos \left( \frac{ Q^i g_{ij} a^j }{ \sqrt{Q^i g_{ij} Q^j} \sqrt{a^i g_{ij} a^j} } \right) } \end{equation}
The sign, $\sigma_{\mathrm{side}}$, of $\xi$ depends on which side of the orientation vector $\left| a \right>$ the scattering vector $\left| Q \right>$ is located. The sign can be found by calculating the (covariant) cross product of $\left| a \right>$ and $\left| Q \right>$ to give an out-of-plane vector which can be compared with the given scattering plane up vector.
\paragraph*{Special case}
Special case for cubic crystals, $g_{ij} = \delta_{ij} \cdot \left( 2\pi / a \right)^2$:
\begin{equation} \xi = \arccos \left( \frac{ Q_i a^i }{ \sqrt{Q_i Q^i} \sqrt{a_i a^i} } \right) \end{equation}
\begin{equation} \xi = \sigma_{\mathrm{side}} \cdot \arccos \left( \frac{ Q_i a^i }{ \sqrt{Q_i Q^i} \sqrt{a_i a^i} } \right) \end{equation}
\end{document}
......@@ -58,6 +58,8 @@ B = np.array([[1,0,0], [0,1,0], [0,0,1]])
orient_rlu = np.array([1,0,0])
#orient2_rlu = np.array([0,1,0])
orient_up_rlu = np.array([0,0,1])
g_eps = 1e-4
# -----------------------------------------------------------------------------
......@@ -209,6 +211,8 @@ editA4 = qtw.QLineEdit(taspanel)
editA5 = qtw.QLineEdit(taspanel)
editA6 = qtw.QLineEdit(taspanel)
checkA4Sense = qtw.QCheckBox(taspanel)
editDm = qtw.QLineEdit(taspanel)
editDa = qtw.QLineEdit(taspanel)
......@@ -227,6 +231,8 @@ separatorTas = qtw.QFrame(Qpanel)
separatorTas.setFrameStyle(qtw.QFrame.HLine)
separatorTas2 = qtw.QFrame(Qpanel)
separatorTas2.setFrameStyle(qtw.QFrame.HLine)
separatorTas3 = qtw.QFrame(Qpanel)
separatorTas3.setFrameStyle(qtw.QFrame.HLine)
def TASChanged():
......@@ -241,6 +247,10 @@ def TASChanged():
dmono = getfloat(editDm.text())
dana = getfloat(editDa.text())
sense_sample = 1.
if checkA4Sense.isChecked() == False:
sense_sample = -1.
editA2.setText("%.6g" % (a2 / np.pi * 180.))
editA6.setText("%.6g" % (a6 / np.pi * 180.))
......@@ -249,7 +259,7 @@ def TASChanged():
kf = tas.get_monok(a5, dana)
E = tas.get_E(ki, kf)
Qlen = tas.get_Q(ki, kf, a4)
Qvec = tas.get_hkl(ki, kf, a3, Qlen, orient_rlu, orient_up_rlu, B)
Qvec = tas.get_hkl(ki, kf, a3, Qlen, orient_rlu, orient_up_rlu, B, sense_sample)
edith.setText("%.6g" % Qvec[0])
editk.setText("%.6g" % Qvec[1])
......@@ -281,7 +291,7 @@ def DChanged():
QChanged()
def QChanged():
global orient_rlu, orient_up_rlu
global orient_rlu, orient_up_rlu, g_eps
Q_rlu = np.array([getfloat(edith.text()), getfloat(editk.text()), getfloat(editl.text())])
ki = getfloat(editKi.text())
......@@ -306,9 +316,13 @@ def QChanged():
editA6.setText("invalid")
try:
[a3, a4, dist_Q_plane] = tas.get_a3a4(ki, kf, Q_rlu, orient_rlu, orient_up_rlu, B)
sense_sample = 1.
if checkA4Sense.isChecked() == False:
sense_sample = -1.
[a3, a4, dist_Q_plane] = tas.get_a3a4(ki, kf, Q_rlu, orient_rlu, orient_up_rlu, B, sense_sample)
Qlen = tas.get_Q(ki, kf, a4)
Q_in_plane = np.abs(dist_Q_plane) < 1e-4
Q_in_plane = np.abs(dist_Q_plane) < g_eps
editA3.setText("%.6g" % (a3 / np.pi * 180.))
editA4.setText("%.6g" % (a4 / np.pi * 180.))
......@@ -371,6 +385,12 @@ editl.setText("%.6g" % sett.value("qtas/l", 0., type=float))
editKi.setText("%.6g" % sett.value("qtas/ki", 2.662, type=float))
editKf.setText("%.6g" % sett.value("qtas/kf", 2.662, type=float))
checkA4Sense.setText("a4 sense is counter-clockwise")
checkA4Sense.setChecked(sett.value("qtas/a4_sense", 1, type=bool))
checkA4Sense.stateChanged.connect(QChanged)
Qlayout.addWidget(qtw.QLabel("h (rlu):", Qpanel), 0,0, 1,1)
Qlayout.addWidget(edith, 0,1, 1,2)
Qlayout.addWidget(qtw.QLabel("k (rlu):", Qpanel), 1,0, 1,1)
......@@ -395,11 +415,14 @@ taslayout.addWidget(qtw.QLabel("a5, a6 (deg):", taspanel), 9,0, 1,1)
taslayout.addWidget(editA5, 9,1, 1,1)
taslayout.addWidget(editA6, 9,2, 1,1)
taslayout.addWidget(separatorTas2, 10,0, 1,3)
taslayout.addWidget(qtw.QLabel("Mono., Ana. d (A):", taspanel), 11,0, 1,1)
taslayout.addWidget(editDm, 11,1, 1,1)
taslayout.addWidget(editDa, 11,2, 1,1)
taslayout.addItem(qtw.QSpacerItem(16,16, qtw.QSizePolicy.Minimum, qtw.QSizePolicy.Expanding), 12,0, 1,3)
taslayout.addWidget(tasstatus, 13,0, 1,3)
taslayout.addWidget(qtw.QLabel("Sense:", taspanel), 11,0, 1,1)
taslayout.addWidget(checkA4Sense, 11,1, 1,2)
taslayout.addWidget(separatorTas3, 12,0, 1,3)
taslayout.addWidget(qtw.QLabel("Mono., Ana. d (A):", taspanel), 13,0, 1,1)
taslayout.addWidget(editDm, 13,1, 1,1)
taslayout.addWidget(editDa, 13,2, 1,1)
taslayout.addItem(qtw.QSpacerItem(16,16, qtw.QSizePolicy.Minimum, qtw.QSizePolicy.Expanding), 14,0, 1,3)
taslayout.addWidget(tasstatus, 15,0, 1,3)
tabs.addTab(taspanel, "TAS")
# -----------------------------------------------------------------------------
......@@ -489,5 +512,6 @@ sett.setValue("qtas/l", getfloat(editl.text()))
sett.setValue("qtas/ki", getfloat(editKi.text()))
sett.setValue("qtas/kf", getfloat(editKf.text()))
sett.setValue("qtas/a3_conv", comboA3.currentIndex())
sett.setValue("qtas/a4_sense", checkA4Sense.isChecked())
sett.setValue("qtas/geo", dlg.saveGeometry())
# -----------------------------------------------------------------------------
......@@ -113,9 +113,9 @@ def get_Q(ki, kf, a4):
# -----------------------------------------------------------------------------
# angle enclosed by ki and Q
def get_psi(ki, kf, Q):
def get_psi(ki, kf, Q, sense=1.):
c = (ki**2. + Q**2. - kf**2.) / (2.*ki*Q)
return np.arccos(c)
return sense*np.arccos(c)
# crystallographic A matrix converting fractional to lab coordinates
......@@ -154,8 +154,9 @@ def get_UB(B, orient1_rlu, orient2_rlu, orientup_rlu):
UB = np.dot(U_invA, B)
return UB
# a3 & a4 angles
def get_a3a4(ki, kf, Q_rlu, orient_rlu, orient_up_rlu, B):
def get_a3a4(ki, kf, Q_rlu, orient_rlu, orient_up_rlu, B, sense_sample=1.):
metric = get_metric(B)
# angle xi between Q and orientation reflex
......@@ -173,7 +174,7 @@ def get_a3a4(ki, kf, Q_rlu, orient_rlu, orient_up_rlu, B):
dist_Q_plane = dot(Q_rlu, orient_up_rlu, metric) / up_len
# angle psi enclosed by ki and Q
psi = get_psi(ki, kf, Qlen)
psi = get_psi(ki, kf, Qlen, sense_sample)
a3 = - psi - xi + a3_offs
a4 = get_a4(ki, kf, Qlen)
......@@ -182,11 +183,11 @@ def get_a3a4(ki, kf, Q_rlu, orient_rlu, orient_up_rlu, B):
return [a3, a4, dist_Q_plane]
def get_hkl(ki, kf, a3, Qlen, orient_rlu, orient_up_rlu, B):
def get_hkl(ki, kf, a3, Qlen, orient_rlu, orient_up_rlu, B, sense_sample=1.):
B_inv = la.inv(B)
# angle enclosed by ki and Q
psi = get_psi(ki, kf, Qlen)
psi = get_psi(ki, kf, Qlen, sense_sample)
# angle between Q and orientation reflex
xi = - a3 + a3_offs - psi
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment