Skip to content
Snippets Groups Projects
Commit 939a20c7 authored by Tobias WEBER's avatar Tobias WEBER
Browse files

tas calculations

parent 1af8d689
No related branches found
No related tags found
No related merge requests found
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment