Add analysis of errors based on ray-tracing
1130
dcm-metrology.html
@ -184,10 +184,12 @@ In this section, the impact of an error in the relative pose between the first a
|
|||||||
This is very important in order to:
|
This is very important in order to:
|
||||||
- link a measurement of the x-ray beam position to a default in the crystal position
|
- link a measurement of the x-ray beam position to a default in the crystal position
|
||||||
- understand which pose default will have large impact on the output beam position/orientation
|
- understand which pose default will have large impact on the output beam position/orientation
|
||||||
- calibrate the deformations of the metrology frame using and external metrology measuring the x-ray beam position/orientation
|
- calibrate the deformations of the metrology frame using an external metrology measuring the x-ray beam position/orientation
|
||||||
|
|
||||||
In order to simplify the problem, the first crystal is supposed to be fixed (i.e. ideally positioned), and only the motion of the second crystal is studied.
|
In order to simplify the problem, the first crystal is supposed to be fixed (i.e. ideally positioned), and only the motion of the second crystal is studied.
|
||||||
|
|
||||||
|
In order to easily study that, "ray tracing" techniques are used.
|
||||||
|
|
||||||
** Matlab Init :noexport:ignore:
|
** Matlab Init :noexport:ignore:
|
||||||
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
|
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
|
||||||
<<matlab-dir>>
|
<<matlab-dir>>
|
||||||
@ -197,66 +199,6 @@ In order to simplify the problem, the first crystal is supposed to be fixed (i.e
|
|||||||
<<matlab-init>>
|
<<matlab-init>>
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src matlab
|
|
||||||
bragg = pi/180*linspace(5,75,100);
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
** Axial motion of second crystal
|
|
||||||
Let's consider the relation between the $[y, z]$ motion of the beam and the motion of the second crystal $[z^\prime, R_{y^\prime}, R_{x^\prime}]$.
|
|
||||||
|
|
||||||
#+name: fig:relation_dz_output_beam
|
|
||||||
#+caption: Relation between $d_{z^\prime}$ motion of the second crystal and vertical motion of the beam
|
|
||||||
[[file:figs/relation_dz_output_beam.png]]
|
|
||||||
|
|
||||||
\begin{equation}
|
|
||||||
d_z = d_{z^\prime} 2 \cos \theta
|
|
||||||
\end{equation}
|
|
||||||
|
|
||||||
#+begin_src matlab :exports none :results none
|
|
||||||
%% Relation between vertical motion of the second crystal and vertical motion of the output beam
|
|
||||||
figure;
|
|
||||||
hold on;
|
|
||||||
plot(180/pi*bragg, 2*cos(bragg))
|
|
||||||
xlabel('Bragg [deg]'); ylabel('Motion amplification');
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab :tangle no :exports results :results file replace
|
|
||||||
exportFig('figs/relation_vert_motion_crystal_beam.pdf', 'width', 'wide', 'height', 'normal');
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+name: fig:relation_vert_motion_crystal_beam
|
|
||||||
#+caption: Relation between vertical motion of the second crystal and vertical motion of the output beam
|
|
||||||
#+RESULTS:
|
|
||||||
[[file:figs/relation_vert_motion_crystal_beam.png]]
|
|
||||||
|
|
||||||
** Ry motion of second crystal
|
|
||||||
|
|
||||||
\begin{equation}
|
|
||||||
d_z = D_{\text{vlm}} d_{R_y^\prime}
|
|
||||||
\end{equation}
|
|
||||||
|
|
||||||
with $D_{\text{vlm}} \approx 10\,m$.
|
|
||||||
|
|
||||||
** Rx motion of second crystal
|
|
||||||
|
|
||||||
\begin{equation}
|
|
||||||
d_y = 2 D_{\text{vlm}} \sin \theta \cdot d_{R_x^\prime}
|
|
||||||
\end{equation}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* Ray Tracing
|
|
||||||
** Introduction :ignore:
|
|
||||||
|
|
||||||
** Matlab Init :noexport:ignore:
|
|
||||||
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
|
|
||||||
<<matlab-dir>>
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab :exports none :results silent :noweb yes
|
|
||||||
<<matlab-init>>
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab :tangle no :noweb yes
|
#+begin_src matlab :tangle no :noweb yes
|
||||||
<<m-init-path>>
|
<<m-init-path>>
|
||||||
#+end_src
|
#+end_src
|
||||||
@ -280,271 +222,73 @@ d_y = 2 D_{\text{vlm}} \sin \theta \cdot d_{R_x^\prime}
|
|||||||
| output beam | =x3,y3,z3= | =s3= |
|
| output beam | =x3,y3,z3= | =s3= |
|
||||||
| Dectector | =xd,yd,zd= | =nd= |
|
| Dectector | =xd,yd,zd= | =nd= |
|
||||||
|
|
||||||
#+begin_src matlab
|
- [ ] Add schematic
|
||||||
theta = 85*pi/180; % [rad]
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
Notations for the pose of the output beam: =d_b_y=, =d_b_z=, =r_b_y=, =r_b_z=.
|
||||||
thetas = pi/180*[5:1:85];
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
$d_{b,y}, d_{b,z}, r_{b,y}, r_{b,z}$
|
||||||
yz = zeros(2, length(thetas));
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
The xy position of the beam is taken in the $x=0$ plane.
|
||||||
for i = 1:length(thetas)
|
|
||||||
theta = thetas(i);
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
** Effect of an error in crystal's distance
|
||||||
%% Secondary crystal defaults
|
<<sec:ray_tracing_dz>>
|
||||||
drx = 0; % [rad]
|
|
||||||
dry = 0; % [rad]
|
|
||||||
dz = 1e-9; % [m]
|
|
||||||
|
|
||||||
% Rotation matrix for drx
|
In Figure [[fig:ray_tracing_error_dz_overview]] is shown the light path for three bragg angles (5, 55 and 85 degrees) when there is an error in the =dz= position of 1mm.
|
||||||
udrx = [cos(theta), 0, -sin(theta)];
|
|
||||||
Rdrx = cos(drx)*eye(3)+sin(drx)*[0, -udrx(3), udrx(2); udrx(3), 0, -udrx(1); -udrx(2), udrx(1), 0] + (1-cos(drx))*(udrx'*udrx);
|
|
||||||
|
|
||||||
% Rotation matrix for dry
|
Visually, it is clear that this induce a =z= offset of the output beam.
|
||||||
Rdry = [ cos(dry), 0, sin(dry); ...
|
|
||||||
0, 1, 0; ...
|
|
||||||
-sin(dry), 0, cos(dry)];
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
|
||||||
%% Input Beam
|
|
||||||
p1 = [-0.1, 0, 0]; % [m]
|
|
||||||
s1 = [ 1, 0, 0];
|
|
||||||
|
|
||||||
%% Primary Mirror
|
|
||||||
pp = [0, 0, 0]; % [m]
|
|
||||||
np = [cos(pi/2-theta), 0, sin(pi/2-theta)];
|
|
||||||
|
|
||||||
%% Reflected beam
|
|
||||||
[p2, s2] = get_plane_reflection(p1, s1, pp, np);
|
|
||||||
|
|
||||||
%% Secondary Mirror
|
|
||||||
ps = pp ...
|
|
||||||
+ 0.07*[cos(theta), 0, -sin(theta)] ... % x offset (does not matter a lot)
|
|
||||||
- np*10e-3./(2*cos(theta)) ... % Theoretical offset
|
|
||||||
+ np*dz; % Add error in distance
|
|
||||||
|
|
||||||
ns = [Rdry*Rdrx*[cos(pi/2-theta), 0, sin(pi/2-theta)]']'; % Normal
|
|
||||||
|
|
||||||
%% Output Beam
|
|
||||||
[p3, s3] = get_plane_reflection(p2, s2, ps, ns);
|
|
||||||
|
|
||||||
%% Detector
|
|
||||||
pd = [1, 0, 0]; % [m]
|
|
||||||
nd = [-1, 0, 0];
|
|
||||||
|
|
||||||
%% Get beam position on the decector
|
|
||||||
p4 = get_plane_reflection(p3, s3, pd, nd);
|
|
||||||
yz(:,i) = p4(2:3);
|
|
||||||
end
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
|
||||||
figure;
|
|
||||||
hold on;
|
|
||||||
plot(180/pi*thetas, 1e9*(yz(2,:) + 10e-3));
|
|
||||||
xlabel('Bragg Angle [deg]'); ylabel('Z position [nm/m/nrad]');
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
|
||||||
figure;
|
|
||||||
hold on;
|
|
||||||
plot(180/pi*thetas, 1e9*yz(1,:));
|
|
||||||
xlabel('Bragg Angle [deg]'); ylabel('Y position [nm/m/nrad]');
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
|
||||||
%% Primary crystal plane
|
|
||||||
z = np;
|
|
||||||
y = [0,1,0];
|
|
||||||
x = cross(y,z);
|
|
||||||
xtal1_rectangle = [pp + 0.02*y + 0.07*x;
|
|
||||||
pp - 0.02*y + 0.07*x;
|
|
||||||
pp - 0.02*y - 0.07*x;
|
|
||||||
pp + 0.02*y - 0.07*x];
|
|
||||||
|
|
||||||
%% Secondary crystal plane
|
|
||||||
z = ns;
|
|
||||||
y = [0,cos(drx),sin(drx)];
|
|
||||||
x = cross(y,z);
|
|
||||||
xtal2_rectangle = [ps + 0.02*y + 0.07*x;
|
|
||||||
ps - 0.02*y + 0.07*x;
|
|
||||||
ps - 0.02*y - 0.07*x;
|
|
||||||
ps + 0.02*y - 0.07*x];
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
|
||||||
figure;
|
|
||||||
tiledlayout(2, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
|
|
||||||
|
|
||||||
ax1 = nexttile();
|
|
||||||
hold on;
|
|
||||||
plot3([p1(1), p2(1)],[p1(2), p2(2)], [p1(3), p2(3)])
|
|
||||||
plot3([p2(1), p3(1)],[p2(2), p3(2)], [p2(3), p3(3)])
|
|
||||||
plot3([p3(1), p3(1)+0.3*s3(1)],[p3(2), p3(2)+0.3*s3(2)], [p3(3), p3(3)+0.3*s3(3)])
|
|
||||||
patch(xtal1_rectangle(:,1), xtal1_rectangle(:,2), xtal1_rectangle(:,3), 'k')
|
|
||||||
patch(xtal2_rectangle(:,1), xtal2_rectangle(:,2), xtal2_rectangle(:,3), 'k')
|
|
||||||
hold off;
|
|
||||||
view(0,0)
|
|
||||||
axis equal
|
|
||||||
xlim([-0.1, 0.15])
|
|
||||||
zlim([-0.02, 0.01])
|
|
||||||
grid off;
|
|
||||||
xlabel('X')
|
|
||||||
ylabel('Y')
|
|
||||||
zlabel('Z')
|
|
||||||
|
|
||||||
ax2 = nexttile();
|
|
||||||
hold on;
|
|
||||||
plot3([p1(1), p2(1)],[p1(2), p2(2)], [p1(3), p2(3)])
|
|
||||||
plot3([p2(1), p3(1)],[p2(2), p3(2)], [p2(3), p3(3)])
|
|
||||||
plot3([p3(1), p3(1)+0.3*s3(1)],[p3(2), p3(2)+0.3*s3(2)], [p3(3), p3(3)+0.3*s3(3)])
|
|
||||||
patch(xtal1_rectangle(:,1), xtal1_rectangle(:,2), xtal1_rectangle(:,3), 'k')
|
|
||||||
patch(xtal2_rectangle(:,1), xtal2_rectangle(:,2), xtal2_rectangle(:,3), 'k')
|
|
||||||
hold off;
|
|
||||||
view(0,90)
|
|
||||||
axis equal
|
|
||||||
xlim([-0.1, 0.15])
|
|
||||||
zlim([-0.02, 0.01])
|
|
||||||
grid off;
|
|
||||||
xlabel('X')
|
|
||||||
ylabel('Y')
|
|
||||||
zlabel('Z')
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
|
||||||
figure;
|
|
||||||
hold on;
|
|
||||||
plot3([p1(1), p2(1)],[p1(2), p2(2)], [p1(3), p2(3)])
|
|
||||||
plot3([p2(1), p3(1)],[p2(2), p3(2)], [p2(3), p3(3)])
|
|
||||||
plot3([p3(1), p3(1)+0.3*s3(1)],[p3(2), p3(2)+0.3*s3(2)], [p3(3), p3(3)+0.3*s3(3)])
|
|
||||||
surf(xtal1_x, xtal1_y, xtal1_z)
|
|
||||||
patch(xtal2_rectangle(:,1), xtal2_rectangle(:,2), xtal2_rectangle(:,3), 'k')
|
|
||||||
hold off;
|
|
||||||
view(0,0)
|
|
||||||
axis equal
|
|
||||||
xlim([-0.1, 0.15])
|
|
||||||
zlim([-0.02, 0.01])
|
|
||||||
grid off;
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
|
||||||
figure;
|
|
||||||
hold on;
|
|
||||||
plot3([p1(1), p2(1)],[p1(2), p2(2)], [p1(3), p2(3)])
|
|
||||||
plot3([p2(1), p3(1)],[p2(2), p3(2)], [p2(3), p3(3)])
|
|
||||||
plot3([p3(1), p3(1)+0.3*s3(1)],[p3(2), p3(2)+0.3*s3(2)], [p3(3), p3(3)+0.3*s3(3)])
|
|
||||||
surf(xtal1_x, xtal1_y, xtal1_z)
|
|
||||||
patch(xtal2_rectangle(:,1), xtal2_rectangle(:,2), xtal2_rectangle(:,3), 'k')
|
|
||||||
hold off;
|
|
||||||
view(90,90)
|
|
||||||
axis equal
|
|
||||||
xlim([-0.1, 0.15])
|
|
||||||
zlim([-0.02, 0.01])
|
|
||||||
grid off;
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
** Effect of =dry=
|
|
||||||
#+begin_src matlab :exports none
|
|
||||||
%% Effect of dry
|
|
||||||
thetas = 1:1:85;
|
|
||||||
Dy = zeros(length(thetas), 1);
|
|
||||||
Dz = zeros(length(thetas), 1);
|
|
||||||
Ry = zeros(length(thetas), 1);
|
|
||||||
Rz = zeros(length(thetas), 1);
|
|
||||||
for i = 1:length(thetas)
|
|
||||||
results = getBeamPath(thetas(i)*pi/180, 'dry', 1e-9);
|
|
||||||
Dy(i) = results.p4(2);
|
|
||||||
Dz(i) = results.p4(3);
|
|
||||||
Ry(i) = atan2(results.s3(3), results.s3(1));
|
|
||||||
Rz(i) = atan2(results.s3(2), results.s3(1));
|
|
||||||
end
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab :exports none :results none
|
#+begin_src matlab :exports none :results none
|
||||||
%% Motion of the output beam with dry error
|
%% Visual Effect of an error in dz
|
||||||
figure;
|
figure;
|
||||||
hold on;
|
hold on;
|
||||||
plot(thetas, 1e9*(Dz+10e-3), '--', 'DisplayName', 'Dz');
|
for theta = [5, 55, 85]
|
||||||
plot(thetas, 1e9*Dy, '--', 'DisplayName', 'Dy');
|
results = getBeamPath(theta*pi/180, 'dz', 1e-3);
|
||||||
plot(thetas, 1e9*Rz, 'DisplayName', 'Rz');
|
set(gca,'ColorOrderIndex',1)
|
||||||
plot(thetas, 1e9*Ry, 'DisplayName', 'Ry');
|
plotBeamPath(results);
|
||||||
|
plotCrystals(results);
|
||||||
|
end
|
||||||
hold off;
|
hold off;
|
||||||
xlabel('Bragg [deg]'); ylabel('Offset [nm/m], Tilt [nrad]')
|
view(0,0)
|
||||||
legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 2);
|
xlim([-10, 15])
|
||||||
xlim([0, 85]);
|
zlim([-4, 2])
|
||||||
|
grid off;
|
||||||
|
axis equal
|
||||||
|
xlabel('X [cm]')
|
||||||
|
ylabel('Y [cm]')
|
||||||
|
zlabel('Z [cm]')
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src matlab :tangle no :exports results :results file replace
|
#+begin_src matlab :tangle no :exports results :results file replace
|
||||||
exportFig('figs/motion_beam_dry_error.pdf', 'width', 'wide', 'height', 'normal');
|
exportFig('figs/ray_tracing_error_dz_overview.pdf', 'width', 'full', 'height', 'normal');
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+name: fig:motion_beam_dry_error
|
#+name: fig:ray_tracing_error_dz_overview
|
||||||
#+caption: Motion of the output beam with dry error
|
#+caption: Visual Effect of an error in =dz= (1mm). Side view.
|
||||||
#+RESULTS:
|
#+RESULTS:
|
||||||
[[file:figs/motion_beam_dry_error.png]]
|
[[file:figs/ray_tracing_error_dz_overview.png]]
|
||||||
|
|
||||||
** Effect of =drx=
|
The motion of the output beam is displayed as a function of the Bragg angle in Figure [[fig:motion_beam_dz_error]].
|
||||||
#+begin_src matlab :exports none
|
It is clear that an error in the distance =dz= between the crystals only induce a =z= offset of the output beam.
|
||||||
%% Effect of drx
|
This offset decreases with the Bragg angle.
|
||||||
thetas = 1:1:85;
|
|
||||||
Dy = zeros(length(thetas), 1);
|
|
||||||
Dz = zeros(length(thetas), 1);
|
|
||||||
Ry = zeros(length(thetas), 1);
|
|
||||||
Rz = zeros(length(thetas), 1);
|
|
||||||
for i = 1:length(thetas)
|
|
||||||
results = getBeamPath(thetas(i)*pi/180, 'drx', 1e-9);
|
|
||||||
Dy(i) = results.p4(2);
|
|
||||||
Dz(i) = results.p4(3);
|
|
||||||
Ry(i) = atan2(results.s3(3), results.s3(1));
|
|
||||||
Rz(i) = atan2(results.s3(2), results.s3(1));
|
|
||||||
end
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab :exports none :results none
|
This is indeed equal to:
|
||||||
%% Motion of the output beam with drx error
|
\begin{equation}
|
||||||
figure;
|
\boxed{d_{b,z} = 2 d_z \cos \theta}
|
||||||
hold on;
|
\end{equation}
|
||||||
plot(thetas, 1e9*(Dz+10e-3), '--', 'DisplayName', 'Dz');
|
|
||||||
plot(thetas, 1e9*Dy, '--', 'DisplayName', 'Dy');
|
|
||||||
plot(thetas, 1e9*Rz, 'DisplayName', 'Rz');
|
|
||||||
plot(thetas, 1e9*Ry, 'DisplayName', 'Ry');
|
|
||||||
hold off;
|
|
||||||
xlabel('Bragg [deg]'); ylabel('Offset [nm/m], Tilt [nrad]')
|
|
||||||
legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 2);
|
|
||||||
xlim([0, 85]);
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab :tangle no :exports results :results file replace
|
|
||||||
exportFig('figs/motion_beam_drx_error.pdf', 'width', 'wide', 'height', 'normal');
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+name: fig:motion_beam_drx_error
|
|
||||||
#+caption: Motion of the output beam with drx error
|
|
||||||
#+RESULTS:
|
|
||||||
[[file:figs/motion_beam_drx_error.png]]
|
|
||||||
|
|
||||||
** Effect of =dz=
|
|
||||||
#+begin_src matlab :exports none
|
#+begin_src matlab :exports none
|
||||||
%% Effect of dz
|
%% Effect of dz
|
||||||
thetas = 1:1:85;
|
thetas = 1:1:85;
|
||||||
Dy = zeros(length(thetas), 1);
|
Dy = zeros(length(thetas), 1); % [m]
|
||||||
Dz = zeros(length(thetas), 1);
|
Dz = zeros(length(thetas), 1); % [m]
|
||||||
Ry = zeros(length(thetas), 1);
|
Ry = zeros(length(thetas), 1); % [rad]
|
||||||
Rz = zeros(length(thetas), 1);
|
Rz = zeros(length(thetas), 1); % [rad]
|
||||||
for i = 1:length(thetas)
|
for i = 1:length(thetas)
|
||||||
results = getBeamPath(thetas(i)*pi/180, 'dz', 1e-9);
|
results = getBeamPath(thetas(i)*pi/180, 'dz', 1e-9);
|
||||||
Dy(i) = results.p4(2);
|
|
||||||
Dz(i) = results.p4(3);
|
|
||||||
Ry(i) = atan2(results.s3(3), results.s3(1));
|
Ry(i) = atan2(results.s3(3), results.s3(1));
|
||||||
Rz(i) = atan2(results.s3(2), results.s3(1));
|
Rz(i) = atan2(results.s3(2), results.s3(1));
|
||||||
|
Dy(i) = results.p4(2)-tan(Rz(i));
|
||||||
|
Dz(i) = results.p4(3)+tan(Ry(i));
|
||||||
end
|
end
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
@ -552,12 +296,12 @@ end
|
|||||||
%% Motion of the output beam with dZ error
|
%% Motion of the output beam with dZ error
|
||||||
figure;
|
figure;
|
||||||
hold on;
|
hold on;
|
||||||
plot(thetas, 1e9*(Dz+10e-3), '--', 'DisplayName', 'Dz');
|
|
||||||
plot(thetas, 1e9*Dy, '--', 'DisplayName', 'Dy');
|
plot(thetas, 1e9*Dy, '--', 'DisplayName', 'Dy');
|
||||||
plot(thetas, 1e9*Rz, 'DisplayName', 'Rz');
|
plot(thetas, 1e9*(Dz+10e-3), '--', 'DisplayName', 'Dz');
|
||||||
plot(thetas, 1e9*Ry, 'DisplayName', 'Ry');
|
plot(thetas, 1e9*Ry, 'DisplayName', 'Ry');
|
||||||
|
plot(thetas, 1e9*Rz, 'DisplayName', 'Rz');
|
||||||
hold off;
|
hold off;
|
||||||
xlabel('Bragg [deg]'); ylabel('Offset [nm/m], Tilt [nrad]')
|
xlabel('Bragg [deg]'); ylabel('Offset [m/m] Tilt [rad/m]')
|
||||||
legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 2);
|
legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 2);
|
||||||
xlim([0, 85]);
|
xlim([0, 85]);
|
||||||
#+end_src
|
#+end_src
|
||||||
@ -571,98 +315,338 @@ exportFig('figs/motion_beam_dz_error.pdf', 'width', 'wide', 'height', 'normal');
|
|||||||
#+RESULTS:
|
#+RESULTS:
|
||||||
[[file:figs/motion_beam_dz_error.png]]
|
[[file:figs/motion_beam_dz_error.png]]
|
||||||
|
|
||||||
** Test :noexport:
|
** Effect of an error in crystal's x parallelism
|
||||||
#+begin_src matlab
|
<<sec:ray_tracing_rx>>
|
||||||
figure;
|
|
||||||
plot(thetas, 1e9*yz(:,1));
|
|
||||||
xlabel('Bragg [deg]'); ylabel('Y Displacement [nm/m/nrad]')
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
The effect of an error in =rx= crystal parallelism on the output beam is visually shown in Figure [[fig:ray_tracing_error_drx_overview]] for three bragg angles (5, 55 and 85 degrees).
|
||||||
figure;
|
The error is set to one degree, and the top view is shown.
|
||||||
plot(thetas, 1e9*yz(:,1));
|
It is clear that the output beam experiences some rotation around a vertical axis.
|
||||||
xlabel('Bragg [deg]'); ylabel('Y Displacement [nm/m/nrad]')
|
The amount of rotation depends on the bragg angle.
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
#+begin_src matlab :exports none :results none
|
||||||
%% Effect of dry
|
%% Visual Effect of an error in drx
|
||||||
thetas = 1:1:85;
|
|
||||||
yz = zeros(length(thetas), 2);
|
|
||||||
for i = 1:length(thetas)
|
|
||||||
results = getBeamPath(thetas(i)*pi/180, 'dry', 1e-9);
|
|
||||||
yz(i,:) = results.p4(2:3);
|
|
||||||
end
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
|
||||||
figure;
|
|
||||||
plot(thetas, 1e9*(yz(:,2) + 10e-3));
|
|
||||||
xlabel('Bragg [deg]'); ylabel('Z Displacement [nm/m/nrad]')
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
|
||||||
%% Effect of dz
|
|
||||||
thetas = 1:1:85;
|
|
||||||
yz = zeros(length(thetas), 2);
|
|
||||||
for i = 1:length(thetas)
|
|
||||||
results = getBeamPath(thetas(i)*pi/180, 'dz', 1e-9);
|
|
||||||
yz(i,:) = results.p4(2:3);
|
|
||||||
end
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
|
||||||
figure;
|
|
||||||
plot(thetas, 1e9*(yz(:,2) + 10e-3));
|
|
||||||
xlabel('Bragg [deg]'); ylabel('Z Displacement [nm/m/nm]')
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#+begin_src matlab
|
|
||||||
figure;
|
figure;
|
||||||
hold on;
|
hold on;
|
||||||
for theta = 5:5:85
|
for theta = [5, 55, 85]
|
||||||
|
results = getBeamPath(theta*pi/180, 'drx', -1*pi/180);
|
||||||
set(gca,'ColorOrderIndex',1)
|
set(gca,'ColorOrderIndex',1)
|
||||||
plotBeamPath(getBeamPath(theta*pi/180, 'dz', 1e-3))
|
plotBeamPath(results);
|
||||||
end
|
% plotCrystals(results);
|
||||||
hold off;
|
|
||||||
view(0,0)
|
|
||||||
axis equal
|
|
||||||
xlim([-0.1, 0.15])
|
|
||||||
zlim([-0.02, 0.01])
|
|
||||||
grid off;
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
|
||||||
figure;
|
|
||||||
hold on;
|
|
||||||
for theta = 5:5:85
|
|
||||||
set(gca,'ColorOrderIndex',1)
|
|
||||||
plotBeamPath(getBeamPath(theta*pi/180, 'dry', 1*pi/180))
|
|
||||||
end
|
|
||||||
hold off;
|
|
||||||
view(0,0)
|
|
||||||
axis equal
|
|
||||||
xlim([-0.1, 0.15])
|
|
||||||
zlim([-0.02, 0.01])
|
|
||||||
grid off;
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab
|
|
||||||
figure;
|
|
||||||
hold on;
|
|
||||||
for theta = 5:5:85
|
|
||||||
set(gca,'ColorOrderIndex',1)
|
|
||||||
plotBeamPath(getBeamPath(theta*pi/180, 'drx', 1*pi/180))
|
|
||||||
end
|
end
|
||||||
hold off;
|
hold off;
|
||||||
view(0,90)
|
view(0,90)
|
||||||
axis equal
|
axis equal
|
||||||
xlim([-0.1, 0.15])
|
xlim([-10, 15])
|
||||||
zlim([-0.02, 0.01])
|
ylim([-1, 1])
|
||||||
grid off;
|
grid off;
|
||||||
|
xlabel('X [cm]');
|
||||||
|
ylabel('Y [cm]');
|
||||||
|
zlabel('Z [cm]');
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab :tangle no :exports results :results file replace
|
||||||
|
exportFig('figs/ray_tracing_error_drx_overview.pdf', 'width', 'full', 'height', 'normal');
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+name: fig:ray_tracing_error_drx_overview
|
||||||
|
#+caption: Visual Effect of an error in =drx= (1 degree). Top View.
|
||||||
|
#+RESULTS:
|
||||||
|
[[file:figs/ray_tracing_error_drx_overview.png]]
|
||||||
|
|
||||||
|
The effect of =drx= as a function of the Bragg angle on the output beam pose is computed and shown in Figure [[fig:motion_beam_drx_error]].
|
||||||
|
|
||||||
|
It induces a rotation of the output beam in the =z= direction that depends on the Bragg Angle.
|
||||||
|
It is starting at zero for small bragg angles, and it increases with the bragg angle up to 2 times =drx=.
|
||||||
|
This is indeed equal to:
|
||||||
|
\begin{equation}
|
||||||
|
\boxed{r_{b,z} = 2 r_x \cos \theta}
|
||||||
|
\end{equation}
|
||||||
|
|
||||||
|
If also induces a small $y$ shift of the beam.
|
||||||
|
This shift is due to the fact that the rotation point (around which the second crystal is moved) is changing as a function of bragg.
|
||||||
|
We can note that the $y$ shift is equal to zero for a bragg angle of 45 degrees, at which point the center of rotation of the second crystal is at $x = 0$;
|
||||||
|
|
||||||
|
#+begin_src matlab :exports none
|
||||||
|
%% Effect of drx
|
||||||
|
thetas = 1:1:85;
|
||||||
|
Dy = zeros(length(thetas), 1);
|
||||||
|
Dz = zeros(length(thetas), 1);
|
||||||
|
Ry = zeros(length(thetas), 1);
|
||||||
|
Rz = zeros(length(thetas), 1);
|
||||||
|
for i = 1:length(thetas)
|
||||||
|
results = getBeamPath(thetas(i)*pi/180, 'drx', 1e-9);
|
||||||
|
Ry(i) = atan2(results.s3(3), results.s3(1));
|
||||||
|
Rz(i) = atan2(results.s3(2), results.s3(1));
|
||||||
|
Dy(i) = results.p4(2)-tan(Rz(i));
|
||||||
|
Dz(i) = results.p4(3)+tan(Ry(i));
|
||||||
|
end
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab :exports none :results none
|
||||||
|
%% Motion of the output beam with drx error
|
||||||
|
figure;
|
||||||
|
hold on;
|
||||||
|
plot(thetas, 1e9*Dy, '--', 'DisplayName', 'Dy');
|
||||||
|
plot(thetas, 1e9*(Dz+10e-3), '--', 'DisplayName', 'Dz');
|
||||||
|
plot(thetas, 1e9*Ry, 'DisplayName', 'Ry');
|
||||||
|
plot(thetas, 1e9*Rz, 'DisplayName', 'Rz');
|
||||||
|
hold off;
|
||||||
|
xlabel('Bragg [deg]'); ylabel('Offset [m/rad] Tilt [rad/rad]')
|
||||||
|
legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 2);
|
||||||
|
xlim([0, 85]);
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab :tangle no :exports results :results file replace
|
||||||
|
exportFig('figs/motion_beam_drx_error.pdf', 'width', 'wide', 'height', 'normal');
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+name: fig:motion_beam_drx_error
|
||||||
|
#+caption: Motion of the output beam with drx error
|
||||||
|
#+RESULTS:
|
||||||
|
[[file:figs/motion_beam_drx_error.png]]
|
||||||
|
|
||||||
|
** Effect of an error in crystal's y parallelism
|
||||||
|
<<sec:ray_tracing_ry>>
|
||||||
|
|
||||||
|
The effect of an error in =ry= crystal parallelism on the output beam is visually shown in Figure [[fig:ray_tracing_error_dry_overview]] for three bragg angles (5, 55 and 85 degrees).
|
||||||
|
|
||||||
|
#+begin_src matlab :exports none :results none
|
||||||
|
%% Visual Effect of an error in dry
|
||||||
|
figure;
|
||||||
|
hold on;
|
||||||
|
for theta = [5, 55, 85]
|
||||||
|
results = getBeamPath(theta*pi/180, 'dry', -1*pi/180);
|
||||||
|
set(gca,'ColorOrderIndex',1)
|
||||||
|
plotBeamPath(results);
|
||||||
|
plotCrystals(results);
|
||||||
|
end
|
||||||
|
hold off;
|
||||||
|
view(0,0)
|
||||||
|
axis equal
|
||||||
|
xlim([-10, 15])
|
||||||
|
zlim([-4, 2])
|
||||||
|
grid off;
|
||||||
|
xlabel('X [cm]')
|
||||||
|
ylabel('Y [cm]')
|
||||||
|
zlabel('Z [cm]')
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab :tangle no :exports results :results file replace
|
||||||
|
exportFig('figs/ray_tracing_error_dry_overview.pdf', 'width', 'full', 'height', 'normal');
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+name: fig:ray_tracing_error_dry_overview
|
||||||
|
#+caption: Visual Effect of an error in =dry= (1 degree). Side view.
|
||||||
|
#+RESULTS:
|
||||||
|
[[file:figs/ray_tracing_error_dry_overview.png]]
|
||||||
|
|
||||||
|
The effect of =dry= as a function of the Bragg angle on the output beam pose is computed and shown in Figure [[fig:motion_beam_dry_error]].
|
||||||
|
It is clear that this induces a rotation of the output beam in the =y= direction equals to 2 times =dry=:
|
||||||
|
\begin{equation}
|
||||||
|
\boxed{r_{b,z} = 2 r_z}
|
||||||
|
\end{equation}
|
||||||
|
|
||||||
|
It also induces a small vertical motion of the beam (at the $x=0$ location) which is simply due to the fact that the $x$ coordinate of the impact point on the second crystal changes with the Bragg angle.
|
||||||
|
|
||||||
|
#+begin_src matlab :exports none
|
||||||
|
%% Effect of dry
|
||||||
|
thetas = 1:1:85;
|
||||||
|
Dy = zeros(length(thetas), 1);
|
||||||
|
Dz = zeros(length(thetas), 1);
|
||||||
|
Ry = zeros(length(thetas), 1);
|
||||||
|
Rz = zeros(length(thetas), 1);
|
||||||
|
for i = 1:length(thetas)
|
||||||
|
results = getBeamPath(thetas(i)*pi/180, 'dry', 1e-9);
|
||||||
|
Ry(i) = atan2(results.s3(3), results.s3(1));
|
||||||
|
Rz(i) = atan2(results.s3(2), results.s3(1));
|
||||||
|
Dy(i) = results.p4(2)-tan(Rz(i));
|
||||||
|
Dz(i) = results.p4(3)-tan(Ry(i));
|
||||||
|
end
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab :exports none :results none
|
||||||
|
%% Motion of the output beam with dry error
|
||||||
|
figure;
|
||||||
|
hold on;
|
||||||
|
plot(thetas, 1e9*Dy, '--', 'DisplayName', 'Dy');
|
||||||
|
plot(thetas, 1e9*(Dz+10e-3), '--', 'DisplayName', 'Dz');
|
||||||
|
plot(thetas, 1e9*Ry, 'DisplayName', 'Ry');
|
||||||
|
plot(thetas, 1e9*Rz, 'DisplayName', 'Rz');
|
||||||
|
hold off;
|
||||||
|
xlabel('Bragg [deg]'); ylabel('Offset [m/rad] Tilt [rad/rad]')
|
||||||
|
legend('location', 'east', 'FontSize', 8, 'NumColumns', 2);
|
||||||
|
xlim([0, 85]);
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab :tangle no :exports results :results file replace
|
||||||
|
exportFig('figs/motion_beam_dry_error.pdf', 'width', 'wide', 'height', 'normal');
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+name: fig:motion_beam_dry_error
|
||||||
|
#+caption: Motion of the output beam with dry error
|
||||||
|
#+RESULTS:
|
||||||
|
[[file:figs/motion_beam_dry_error.png]]
|
||||||
|
|
||||||
|
** Summary
|
||||||
|
|
||||||
|
Effects of crystal's pose errors on the output beam are summarized in Table [[tab:crystal_pose_beam_pose]].
|
||||||
|
Note that the three pose errors are well decoupled regarding their effects on the output beam.
|
||||||
|
Also note that the effect of an error in crystal's distance does not depend on the Bragg angle.
|
||||||
|
|
||||||
|
#+name: tab:crystal_pose_beam_pose
|
||||||
|
#+caption: Summary of the effects of the errors in second crystal's pose on the output beam
|
||||||
|
#+attr_latex: :environment tabularx :width 0.65\linewidth :align X|ccc
|
||||||
|
#+attr_latex: :center t :booktabs t
|
||||||
|
| *Beam Motion* | *Crystal* $d_z$ | *Crystal* $r_x$ | *Crystal* $r_y$ |
|
||||||
|
|---------------+--------------------------------+--------------------------------------+--------------------|
|
||||||
|
| $d_{b,y}$ | 0 | $\approx 0$ | 0 |
|
||||||
|
| $d_{b,z}$ | $\boxed{d_{z} 2 \cos(\theta)}$ | 0 | $\approx 0$ |
|
||||||
|
| $r_{b,y}$ | 0 | 0 | $\boxed{2 r_{y}}$ |
|
||||||
|
| $r_{b,z}$ | 0 | $\boxed{- r_x 2 \sin(\theta)}$ | 0 |
|
||||||
|
|
||||||
|
** "Channel cut" Scan
|
||||||
|
A "channel cut" scan is a Bragg scan where the distance between the crystals is fixed.
|
||||||
|
|
||||||
|
This is visually shown in Figure [[fig:ray_tracing_channel_cut]] where it is clear that the output beam experiences some vertical motion.
|
||||||
|
|
||||||
|
#+begin_src matlab :exports none :results none
|
||||||
|
%% Visual Effect of a channel cut scan
|
||||||
|
figure;
|
||||||
|
hold on;
|
||||||
|
for theta = [30, 40, 50]
|
||||||
|
results = getBeamPath(theta*pi/180, 'dz', 10e-3/(2*cos(pi/180*theta))-10e-3/(2*cos(pi/180*theta_fixed)));
|
||||||
|
set(gca,'ColorOrderIndex',1)
|
||||||
|
plotBeamPath(results);
|
||||||
|
plotCrystals(results);
|
||||||
|
end
|
||||||
|
hold off;
|
||||||
|
view(0,0)
|
||||||
|
axis equal
|
||||||
|
xlim([-10, 15])
|
||||||
|
zlim([-4, 2])
|
||||||
|
grid off;
|
||||||
|
xlabel('X [cm]')
|
||||||
|
ylabel('Y [cm]')
|
||||||
|
zlabel('Z [cm]')
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab :tangle no :exports results :results file replace
|
||||||
|
exportFig('figs/ray_tracing_channel_cut.pdf', 'width', 'full', 'height', 'normal');
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+name: fig:ray_tracing_channel_cut
|
||||||
|
#+caption: Visual Effect of a channel cut scan
|
||||||
|
#+RESULTS:
|
||||||
|
[[file:figs/ray_tracing_channel_cut.png]]
|
||||||
|
|
||||||
|
The $z$ offset of the beam for several channel cut scans are shown in Figure [[fig:channel_cut_scan]].
|
||||||
|
|
||||||
|
#+begin_src matlab :exports none
|
||||||
|
%% Computation of Z motion of the beam during "channel cut" scans
|
||||||
|
thetas = 5:1:84;
|
||||||
|
Dz = zeros(length(thetas), 1);
|
||||||
|
|
||||||
|
for i = 1:length(thetas)
|
||||||
|
results = getBeamPath(thetas(i)*pi/180, 'dz', 10e-3/(2*cos(pi/180*thetas(i)))-10e-3/(2*cos(pi/180*(10*fix((5+thetas(i))/10)))));
|
||||||
|
Dz(i) = results.p4(3);
|
||||||
|
end
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab :exports none :results none
|
||||||
|
%% Dz motion of the beam during "channel cut" scans
|
||||||
|
figure;
|
||||||
|
hold on;
|
||||||
|
for i = 1:8
|
||||||
|
plot(thetas((i-1)*10+1:i*10), 1e3*(Dz((i-1)*10+1:i*10)+10e-3), '-', 'DisplayName', sprintf('$%i^o$: $%.0f\\,\\mu$m/deg', (10*fix((5+thetas((i-1)*10+5))/10)), 1e6*(Dz((i-1)*10+6)-Dz((i-1)*10+5))));
|
||||||
|
end
|
||||||
|
hold off;
|
||||||
|
xlabel('Bragg [deg]'); ylabel('Dz Offset [mm]')
|
||||||
|
xlim([0, 90]); ylim([-4, 4]);
|
||||||
|
xticks([0:10:90]);
|
||||||
|
legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 2);
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab :tangle no :exports results :results file replace
|
||||||
|
exportFig('figs/channel_cut_scan.pdf', 'width', 'wide', 'height', 'normal');
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+name: fig:channel_cut_scan
|
||||||
|
#+caption: Z motion of the beam during "channel cut" scans
|
||||||
|
#+RESULTS:
|
||||||
|
[[file:figs/channel_cut_scan.png]]
|
||||||
|
|
||||||
|
* Determining relative pose between the crystals using the X-ray
|
||||||
|
** Introduction :ignore:
|
||||||
|
As Interferometers are only measuring /relative/ displacement, it is mandatory to initialize them correctly.
|
||||||
|
|
||||||
|
They should be initialize in such a way that:
|
||||||
|
- $r_x = 0$ and $r_y = 0$ when the two crystallographic planes are parallel
|
||||||
|
- measured $d_z$ is equal to the distance between the crystallographic planes
|
||||||
|
|
||||||
|
In order to do that, an external metrology using the x-ray is used.
|
||||||
|
|
||||||
|
** Determine the $y$ parallelism - "Rocking Curve"
|
||||||
|
|
||||||
|
** Determine the $x$ parallelism - Bragg Scan
|
||||||
|
|
||||||
|
|
||||||
|
** Determine the $z$ distance - Bragg Scan
|
||||||
|
|
||||||
|
** Use Channel cut scan to determine crystal =dry= parallelism
|
||||||
|
|
||||||
|
Now, let's suppose we want to determine the =dry= angle between the crystals.
|
||||||
|
|
||||||
|
#+begin_src matlab
|
||||||
|
dry = 1e-6; % [rad]
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab :exports none
|
||||||
|
%% Computation of Z motion of the beam during "channel cut" scans
|
||||||
|
thetas = 5:1:84;
|
||||||
|
Dz_expected = zeros(length(thetas), 1);
|
||||||
|
Dz_obtained = zeros(length(thetas), 1);
|
||||||
|
|
||||||
|
for i = 1:length(thetas)
|
||||||
|
results = getBeamPath(thetas(i)*pi/180, 'dz', 10e-3/(2*cos(pi/180*thetas(i)))-10e-3/(2*cos(pi/180*(10*fix((5+thetas(i))/10)))));
|
||||||
|
Dz_expected(i) = results.p4(3);
|
||||||
|
|
||||||
|
results = getBeamPath(thetas(i)*pi/180, 'dz', 10e-3/(2*cos(pi/180*thetas(i)))-10e-3/(2*cos(pi/180*(10*fix((5+thetas(i))/10)))), 'dry', dry);
|
||||||
|
Dz_obtained(i) = results.p4(3);
|
||||||
|
end
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
The error is
|
||||||
|
\begin{equation}
|
||||||
|
\boxed{d_{b,z} = -2 d_z \cos()}
|
||||||
|
\end{equation}
|
||||||
|
|
||||||
|
#+begin_src matlab :exports none :results none
|
||||||
|
%% Dz motion of the beam during "channel cut" scans
|
||||||
|
figure;
|
||||||
|
hold on;
|
||||||
|
plot(thetas, 1e6*(Dz_expected-Dz_obtained), '-');
|
||||||
|
hold off;
|
||||||
|
xlabel('Bragg [deg]'); ylabel('Dz Offset [$\mu$m]')
|
||||||
|
xlim([0, 90]);
|
||||||
|
xticks([0:10:90]);
|
||||||
|
legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 2);
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab :exports none :results none
|
||||||
|
%% Dz motion of the beam during "channel cut" scans
|
||||||
|
figure;
|
||||||
|
hold on;
|
||||||
|
plot(thetas, 1e3*Dz_expected, '-');
|
||||||
|
plot(thetas, 1e3*Dz_obtained, '-');
|
||||||
|
hold off;
|
||||||
|
xlabel('Bragg [deg]'); ylabel('Dz Offset [mm]')
|
||||||
|
xlim([0, 90]);
|
||||||
|
xticks([0:10:90]);
|
||||||
|
legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 2);
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Effect of an error on Bragg angle
|
||||||
|
|
||||||
* Deformations of the Metrology Frame
|
* Deformations of the Metrology Frame
|
||||||
<<sec:frame_deformations>>
|
<<sec:frame_deformations>>
|
||||||
** Introduction :ignore:
|
** Introduction :ignore:
|
||||||
@ -1396,16 +1380,16 @@ freqs = logspace(1, 3, 1000);
|
|||||||
|
|
||||||
** Intersection between Ray and Plane
|
** Intersection between Ray and Plane
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:header-args:matlab+: :tangle matlab/src/get_plane_reflection.m
|
:header-args:matlab+: :tangle matlab/src/getPlaneReflection.m
|
||||||
:header-args:matlab+: :comments none :mkdirp yes :eval no
|
:header-args:matlab+: :comments none :mkdirp yes :eval no
|
||||||
:END:
|
:END:
|
||||||
<<sec:get_plane_reflection>>
|
<<sec:getPlaneReflection>>
|
||||||
|
|
||||||
#+begin_src matlab
|
#+begin_src matlab
|
||||||
function [p_reflect, s_reflect] = get_plane_reflection(p_in, s_in, p_plane, n_plane)
|
function [p_reflect, s_reflect] = getPlaneReflection(p_in, s_in, p_plane, n_plane)
|
||||||
% get_plane_reflection -
|
% getPlaneReflection -
|
||||||
%
|
%
|
||||||
% Syntax: [p_reflect, s_reflect] = get_plane_reflection(p_in, s_in, p_plane, n_plane)
|
% Syntax: [p_reflect, s_reflect] = getPlaneReflection(p_in, s_in, p_plane, n_plane)
|
||||||
%
|
%
|
||||||
% Inputs:
|
% Inputs:
|
||||||
% - p_in, s_in, p_plane, n_plane -
|
% - p_in, s_in, p_plane, n_plane -
|
||||||
@ -1474,25 +1458,25 @@ pp = [0, 0, 0]; % [m]
|
|||||||
np = [cos(pi/2-theta), 0, sin(pi/2-theta)];
|
np = [cos(pi/2-theta), 0, sin(pi/2-theta)];
|
||||||
|
|
||||||
%% Reflected beam
|
%% Reflected beam
|
||||||
[p2, s2] = get_plane_reflection(p1, s1, pp, np);
|
[p2, s2] = getPlaneReflection(p1, s1, pp, np);
|
||||||
|
|
||||||
%% Secondary Mirror
|
%% Secondary Mirror
|
||||||
ps = pp ...
|
ps = pp ...
|
||||||
+ 0.07*[cos(theta), 0, -sin(theta)] ... % x offset (does not matter a lot)
|
+ 0.032*[cos(theta), 0, -sin(theta)] ... % x offset (does not matter a lot)
|
||||||
- np*10e-3./(2*cos(theta)) ... % Theoretical offset
|
- np*10e-3./(2*cos(theta)) ... % Theoretical offset
|
||||||
+ np*args.dz; % Add error in distance
|
+ np*args.dz; % Add error in distance
|
||||||
|
|
||||||
ns = [Rdry*Rdrx*[cos(pi/2-theta), 0, sin(pi/2-theta)]']'; % Normal
|
ns = [Rdry*Rdrx*[cos(pi/2-theta), 0, sin(pi/2-theta)]']'; % Normal
|
||||||
|
|
||||||
%% Output Beam
|
%% Output Beam
|
||||||
[p3, s3] = get_plane_reflection(p2, s2, ps, ns);
|
[p3, s3] = getPlaneReflection(p2, s2, ps, ns);
|
||||||
|
|
||||||
%% Detector
|
%% Detector
|
||||||
pd = [1, 0, 0]; % [m]
|
pd = [1, 0, 0]; % [m]
|
||||||
nd = [-1, 0, 0];
|
nd = [-1, 0, 0];
|
||||||
|
|
||||||
%% Get beam position on the decector
|
%% Get beam position on the decector
|
||||||
p4 = get_plane_reflection(p3, s3, pd, nd);
|
p4 = getPlaneReflection(p3, s3, pd, nd);
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src matlab
|
#+begin_src matlab
|
||||||
@ -1535,8 +1519,65 @@ function [] = plotBeamPath(results)
|
|||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_src matlab
|
#+begin_src matlab
|
||||||
plot3([results.p1(1), results.p2(1)],[results.p1(2), results.p2(2)], [results.p1(3), results.p2(3)])
|
plot3(100*[results.p1(1), results.p2(1)],100*[results.p1(2), results.p2(2)], 100*[results.p1(3), results.p2(3)], 'linewidth', 0.5)
|
||||||
plot3([results.p2(1), results.p3(1)],[results.p2(2), results.p3(2)], [results.p2(3), results.p3(3)])
|
plot3(100*[results.p2(1), results.p3(1)],100*[results.p2(2), results.p3(2)], 100*[results.p2(3), results.p3(3)], 'linewidth', 0.5)
|
||||||
plot3([results.p3(1), results.p4(1)],[results.p3(2), results.p4(2)], [results.p3(3), results.p4(3)])
|
plot3(100*[results.p3(1), results.p4(1)],100*[results.p3(2), results.p4(2)], 100*[results.p3(3), results.p4(3)], 'linewidth', 0.5)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
|
||||||
|
** Plot Crystal
|
||||||
|
:PROPERTIES:
|
||||||
|
:header-args:matlab+: :tangle matlab/src/plotCrystals.m
|
||||||
|
:header-args:matlab+: :comments none :mkdirp yes :eval no
|
||||||
|
:END:
|
||||||
|
<<sec:plotCrystals>>
|
||||||
|
|
||||||
|
#+begin_src matlab
|
||||||
|
function [] = plotCrystals(results, args)
|
||||||
|
% plotCrystals -
|
||||||
|
%
|
||||||
|
% Syntax: [in_data] = plotCrystals(drx, dry, dz, theta, )
|
||||||
|
%
|
||||||
|
% Inputs:
|
||||||
|
% - drx, dry, dz, theta, -
|
||||||
|
%
|
||||||
|
% Outputs:
|
||||||
|
% - in_data -
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab
|
||||||
|
arguments
|
||||||
|
results
|
||||||
|
args.color (3,1) double {mustBeNumeric} = [1;1;1]
|
||||||
|
args.alpha (1,1) double {mustBeNumeric} = 1
|
||||||
|
end
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab
|
||||||
|
z = results.np;
|
||||||
|
y = [0,1,0];
|
||||||
|
x = cross(y,z);
|
||||||
|
xtal1_rectangle = [results.pp + 0.02/2*y + 0.035/2*x;
|
||||||
|
results.pp - 0.02/2*y + 0.035/2*x;
|
||||||
|
results.pp - 0.02/2*y - 0.035/2*x;
|
||||||
|
results.pp + 0.02/2*y - 0.035/2*x];
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab
|
||||||
|
patch(100*xtal1_rectangle(:,1), 100*xtal1_rectangle(:,2), 100*xtal1_rectangle(:,3), 'k-')
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab
|
||||||
|
z = results.ns;
|
||||||
|
% y = [0,cos(drx),sin(drx)];
|
||||||
|
y = [0,1,0];
|
||||||
|
x = cross(y,z);
|
||||||
|
xtal2_rectangle = [results.ps + 0.02/2*y + 0.07/2*x;
|
||||||
|
results.ps - 0.02/2*y + 0.07/2*x;
|
||||||
|
results.ps - 0.02/2*y - 0.07/2*x;
|
||||||
|
results.ps + 0.02/2*y - 0.07/2*x];
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab
|
||||||
|
patch(100*xtal2_rectangle(:,1), 100*xtal2_rectangle(:,2), 100*xtal2_rectangle(:,3), 'k-')
|
||||||
|
#+end_src
|
||||||
|
BIN
figs/channel_cut_scan.pdf
Normal file
BIN
figs/channel_cut_scan.png
Normal file
After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
BIN
figs/ray_tracing_channel_cut.pdf
Normal file
BIN
figs/ray_tracing_channel_cut.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
figs/ray_tracing_error_drx_overview.pdf
Normal file
BIN
figs/ray_tracing_error_drx_overview.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
figs/ray_tracing_error_dry_overview.pdf
Normal file
BIN
figs/ray_tracing_error_dry_overview.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
figs/ray_tracing_error_dz_overview.pdf
Normal file
BIN
figs/ray_tracing_error_dz_overview.png
Normal file
After Width: | Height: | Size: 14 KiB |
@ -34,25 +34,25 @@ pp = [0, 0, 0]; % [m]
|
|||||||
np = [cos(pi/2-theta), 0, sin(pi/2-theta)];
|
np = [cos(pi/2-theta), 0, sin(pi/2-theta)];
|
||||||
|
|
||||||
%% Reflected beam
|
%% Reflected beam
|
||||||
[p2, s2] = get_plane_reflection(p1, s1, pp, np);
|
[p2, s2] = getPlaneReflection(p1, s1, pp, np);
|
||||||
|
|
||||||
%% Secondary Mirror
|
%% Secondary Mirror
|
||||||
ps = pp ...
|
ps = pp ...
|
||||||
+ 0.07*[cos(theta), 0, -sin(theta)] ... % x offset (does not matter a lot)
|
+ 0.032*[cos(theta), 0, -sin(theta)] ... % x offset (does not matter a lot)
|
||||||
- np*10e-3./(2*cos(theta)) ... % Theoretical offset
|
- np*10e-3./(2*cos(theta)) ... % Theoretical offset
|
||||||
+ np*args.dz; % Add error in distance
|
+ np*args.dz; % Add error in distance
|
||||||
|
|
||||||
ns = [Rdry*Rdrx*[cos(pi/2-theta), 0, sin(pi/2-theta)]']'; % Normal
|
ns = [Rdry*Rdrx*[cos(pi/2-theta), 0, sin(pi/2-theta)]']'; % Normal
|
||||||
|
|
||||||
%% Output Beam
|
%% Output Beam
|
||||||
[p3, s3] = get_plane_reflection(p2, s2, ps, ns);
|
[p3, s3] = getPlaneReflection(p2, s2, ps, ns);
|
||||||
|
|
||||||
%% Detector
|
%% Detector
|
||||||
pd = [1, 0, 0]; % [m]
|
pd = [1, 0, 0]; % [m]
|
||||||
nd = [-1, 0, 0];
|
nd = [-1, 0, 0];
|
||||||
|
|
||||||
%% Get beam position on the decector
|
%% Get beam position on the decector
|
||||||
p4 = get_plane_reflection(p3, s3, pd, nd);
|
p4 = getPlaneReflection(p3, s3, pd, nd);
|
||||||
|
|
||||||
results = struct();
|
results = struct();
|
||||||
% Beam position and orientations
|
% Beam position and orientations
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
function [p_reflect, s_reflect] = get_plane_reflection(p_in, s_in, p_plane, n_plane)
|
function [p_reflect, s_reflect] = getPlaneReflection(p_in, s_in, p_plane, n_plane)
|
||||||
% get_plane_reflection -
|
% getPlaneReflection -
|
||||||
%
|
%
|
||||||
% Syntax: [p_reflect, s_reflect] = get_plane_reflection(p_in, s_in, p_plane, n_plane)
|
% Syntax: [p_reflect, s_reflect] = getPlaneReflection(p_in, s_in, p_plane, n_plane)
|
||||||
%
|
%
|
||||||
% Inputs:
|
% Inputs:
|
||||||
% - p_in, s_in, p_plane, n_plane -
|
% - p_in, s_in, p_plane, n_plane -
|
@ -9,6 +9,6 @@ function [] = plotBeamPath(results)
|
|||||||
% Outputs:
|
% Outputs:
|
||||||
% - in_data -
|
% - in_data -
|
||||||
|
|
||||||
plot3([results.p1(1), results.p2(1)],[results.p1(2), results.p2(2)], [results.p1(3), results.p2(3)])
|
plot3(100*[results.p1(1), results.p2(1)],100*[results.p1(2), results.p2(2)], 100*[results.p1(3), results.p2(3)], 'linewidth', 0.5)
|
||||||
plot3([results.p2(1), results.p3(1)],[results.p2(2), results.p3(2)], [results.p2(3), results.p3(3)])
|
plot3(100*[results.p2(1), results.p3(1)],100*[results.p2(2), results.p3(2)], 100*[results.p2(3), results.p3(3)], 'linewidth', 0.5)
|
||||||
plot3([results.p3(1), results.p4(1)],[results.p3(2), results.p4(2)], [results.p3(3), results.p4(3)])
|
plot3(100*[results.p3(1), results.p4(1)],100*[results.p3(2), results.p4(2)], 100*[results.p3(3), results.p4(3)], 'linewidth', 0.5)
|
||||||
|
37
matlab/src/plotCrystals.m
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
function [] = plotCrystals(results, args)
|
||||||
|
% plotCrystals -
|
||||||
|
%
|
||||||
|
% Syntax: [in_data] = plotCrystals(drx, dry, dz, theta, )
|
||||||
|
%
|
||||||
|
% Inputs:
|
||||||
|
% - drx, dry, dz, theta, -
|
||||||
|
%
|
||||||
|
% Outputs:
|
||||||
|
% - in_data -
|
||||||
|
|
||||||
|
arguments
|
||||||
|
results
|
||||||
|
args.color (3,1) double {mustBeNumeric} = [1;1;1]
|
||||||
|
args.alpha (1,1) double {mustBeNumeric} = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
z = results.np;
|
||||||
|
y = [0,1,0];
|
||||||
|
x = cross(y,z);
|
||||||
|
xtal1_rectangle = [results.pp + 0.02/2*y + 0.035/2*x;
|
||||||
|
results.pp - 0.02/2*y + 0.035/2*x;
|
||||||
|
results.pp - 0.02/2*y - 0.035/2*x;
|
||||||
|
results.pp + 0.02/2*y - 0.035/2*x];
|
||||||
|
|
||||||
|
patch(100*xtal1_rectangle(:,1), 100*xtal1_rectangle(:,2), 100*xtal1_rectangle(:,3), 'k-')
|
||||||
|
|
||||||
|
z = results.ns;
|
||||||
|
% y = [0,cos(drx),sin(drx)];
|
||||||
|
y = [0,1,0];
|
||||||
|
x = cross(y,z);
|
||||||
|
xtal2_rectangle = [results.ps + 0.02/2*y + 0.07/2*x;
|
||||||
|
results.ps - 0.02/2*y + 0.07/2*x;
|
||||||
|
results.ps - 0.02/2*y - 0.07/2*x;
|
||||||
|
results.ps + 0.02/2*y - 0.07/2*x];
|
||||||
|
|
||||||
|
patch(100*xtal2_rectangle(:,1), 100*xtal2_rectangle(:,2), 100*xtal2_rectangle(:,3), 'k-')
|