Cartoon of movements of a spherical grating spectrometer
Matlab codes
% Animation of movement of a grating and detector in order to capture the
% energy spectrum from a point source sitting on the Rowland circle.
clear; close all;
vid = VideoWriter('sphericalGratingMovement.mp4','MPEG-4');
vid.Quality = 100;
vid.FrameRate = 30;
open(vid);
figure('units','pixels','position',[0 0 1920 1080],'ToolBar','none');
set(0,'defaultfigurecolor',[1 1 1]);
set(gca,'linewidth',7);
% Create rgb progression through a rainbow
bot = 0:8:120; % 0 to 7f in 16 steps
top = 128:8:248; % 80 to ff
all = 0:16:240; % 0 to ff
botc = 0*all; % vector of zeros
midc = botc + 127; % vector of 127s
topc = botc + 255; % vector of 255s
rcomp = [top topc topc flip(all) botc botc bot flip(bot)]/256; % R in rgb
gcomp = [botc bot top flip(top) midc flip(bot) botc botc]/256; % G in rgb
bcomp = [botc botc botc botc bot midc midc flip(bot)]/256; % B in rgb
LL = 11;
r = 10;
grey = [0.5 0.5 0.5];
phistep = pi/360; % Step size in creating crystal surface
phipos = -pi/12:phistep:pi/12; % Vector of angles moving in positive direction from -15 to +15 deg
phineg = flip(phipos); % Vector of angles moving in negative direction from +15 to -15 deg
fwd = 1:128;
for i = [fwd flip(fwd)]
phi = 10 + (i-1)*70/128;
newplot
hold off
plot([0 0],[-r 2*r],'Color','black','LineWidth',2,'LineStyle','-.'); % vertical line along which the center of the grating moves
hold on
j = 128 - i + 1;
plot([0 0],[0 2*r*sind(phi)],'Color',[rcomp(j) gcomp(j) bcomp(j)],'LineWidth',2);
len = 2*r*sind(phi);
plot([0 len*sind(2*phi)],[len len*(1+cosd(2*phi))],'Color',...
[rcomp(j) gcomp(j) bcomp(j)],'LineWidth',2);
xstx1 = r*(1 - cos(phipos)); % x-coords of inner edge of bent crystal
xstx2 = r*1.05*(1 - cos(phineg)) - r*0.05; % x-coords of outer edge of bent crystal
xstx = [xstx1 xstx2]; % x-coords of bent crystal via concatenation
xsty1 = r*sin(phipos)+2*r*sind(phi); % y-coords of inner edge of bent crystal
xsty2 = r*1.05*sin(phineg)+2*r*sind(phi); % y-coords of outer edge of bent crystal
xsty = [xsty1 xsty2]; % y-coords of bent crystal via concatenation
xst = fill(xstx,xsty,grey,'LineStyle','none');
rotate(xst,[0 0 1],-phi,[0,2*r*sind(phi),0]);
xc = r*cosd(phi);
yc = r*sind(phi);
viscircles([xc yc],r,'LineStyle','-.','LineWidth',2); % Dot-dashed Rowland circle
viscircles([0 0],0.05,'Color','black','LineWidth',5); % Rotation point of Rowland circle
axis equal
axis off
xlim([-LL 2*LL]);
ylim([-LL 2*LL]);
frame = getframe(gcf);
writeVideo(vid,frame);
end
% Output the movie as an mpg file
close(vid);
% Cartoon of a multielement spherical grating monochromator with the
% diffracting elements on individual Rowland circles
clear; close all
vid = VideoWriter('multiRowland.mp4','MPEG-4');
vid.Quality = 100;
vid.FrameRate = 30;
open(vid);
figure('units','pixels','position',[0 0 2800 2000],'ToolBar','none');
set(0,'defaultfigurecolor',[1 1 1]);
% red - yellow - green - blue - violet
rgb = customcolormap([0 0.25 0.5 0.75 1], {'#ff0000','#ffff00','#00ff00','#0000ff','#7f00ff'});
rgb2 = customcolormap([0 0.25 0.5 0.75 1], {'#ff0000','#ffff00','#00ff00','#0000ff','#7f00ff'},128);
rgbbgr = [rgb2; flip(rgb2)];
fliprgb = flip(rgb);
colormap(fliprgb);
myBlue = [0.4 0.44 0.73];
lp = [-7 2 -2];
lp2 = [0 0 2];
rR = 0.5; % Rowland circle radius
theta = 0:pi/180:2*pi;
circlex = 0.5*sin(theta);
circlez = 0.5*cos(theta);
% Set up spherical bowl for crystal analyzer surfaces
[X,Y,Z] = sphere(2000);
X = X/2; Y = Y/2; Z = Z/2; % Sphere radius 0.5
xnot = 0.496;
% Only surviving part of sphere for X > xnot - a small slice of the sphere
X(X<xnot) = NaN ; Y(X<xnot) = NaN ; Z(X<xnot) = NaN;
cylRad = (rR^2-xnot^2)^0.5; % Radius of cylinder defining side wall of crystal analyzers
[a,b,c] = cylinder(cylRad,500);
xstht = 0.05; % Height of side wall of crystal analyzers
detHt = 0.14;
t = 0:1;
r = t;
[xx,yy,zz] = cylinder(r,255);
pos1 = [0 0 1 1];
phiMin = 5;
phiMax = 25;
pt1 = phiMin:0.125:phiMax;
pt2 = phiMax:-0.125:phiMin;
range = [pt1 pt2];
for phi = range % Rotate Rowland circle
colorIndex = floor(256*(phi-phiMin)/(phiMax-phiMin))+1;
if (colorIndex > 256)
colorIndex = 256;
end
Lsx = 2*rR*cosd(phi); % Sample - crystal analyzer distance
rR0x = Lsx*cosd(phi) - rR; % x-value of centre of Rowland circle
rR0z = -Lsx*sind(phi); % z-value of centre of Rowland circle
del = rR - (rR^2 - cylRad^2)^0.5; % Height of lip cf middle of crystal analyzer surface
Lax = Lsx*cosd(phi); % Distance in x-direction from middle of crystal analyzer surface to sample-detector axis
cylOff = -rR0z + Lax + xstht - del;
hold off
subplot('position',pos1);
newplot
hold on
axis off
axis equal
xlim([-0.4 1.1]);
ylim([-0.7 0.7]);
zlim([-0.9 0.5]);
light('Position',lp,'Style','infinite');
light('Position',lp2,'Style','infinite');
view(-50,22);
[V,F]=platonic_solid(4,0.025);
ps1 = patch('Faces',F,'Vertices',V,'FaceColor',myBlue,'FaceAlpha',1,...
'EdgeColor','none','FaceLighting','flat','DiffuseStrength',0.8,...
'SpecularStrength',0.8);
for xst = -3:3
% Crystal analyzer surface
xstsurf = surf(X+rR0x,Y,Z+rR0z,'FaceColor',[0.4 0.4 0.4],'LineStyle','none',...
'FaceLighting','flat','DiffuseStrength',0.4);
rotate(xstsurf,[0 0 1],10*xst,[0,0,rR0z]); % Rotate around vertical z-axis
% Side walls of crystal analyzers
xstside = surf(a,b,xstht*c - cylOff,'FaceColor',[0.8 0.8 0.8],'LineStyle','none',...
'FaceLighting','flat','DiffuseStrength',0.4);
rotate(xstside,[0 1 0],-90,[0,0,rR0z]);
rotate(xstside,[0 0 1],10*xst,[0,0,rR0z]);
% Rowland circles
cc = plot3(circlex+rR0x,0*circlex,circlez+rR0z,'Color',[0.5 0.5 0.5],'LineStyle','-.','LineWidth',0.4);
rotate(cc,[0 0 1],10*xst,[0,0,rR0z]);
% Fluorescent radiation cones
CO(:,:,1) = rgbbgr(:,1).*ones(256,1);
CO(:,:,2) = rgbbgr(:,2).*ones(256,1);
CO(:,:,3) = rgbbgr(:,3).*ones(256,1);
for n = 1:2
COO(n,:,1) = CO(:,:,1);
COO(n,:,2) = CO(:,:,2);
COO(n,:,3) = CO(:,:,3);
end
coneIndex = round(256*abs(xx(2,:))/max(max(xx)));
fluor1 = surf(0.97*cosd(phi)*cylRad*xx, 0.97*cylRad*yy, 1.0133*zz*Lsx,COO,'FaceAlpha',0.4,'LineStyle','none',...
'FaceLighting','flat','DiffuseStrength',0.4);
rotate(fluor1,[0 1 0],90+phi,[0,0,0]);
rotate(fluor1,[0 0 1],10*xst,[0,0,0]);
fluor2 = surf(0.97*cosd(phi)*cylRad*xx, cylRad*yy, 1.0133*zz*Lsx+2*rR0z,'FaceColor',fliprgb(colorIndex,:),'FaceAlpha','0.125','LineStyle','none',...
'FaceLighting','flat','DiffuseStrength',0.4);
rotate(fluor2,[0 1 0],90-phi,[0,0,2*rR0z]);
rotate(fluor2,[0 0 1],10*xst,[0,0,0]);
end
% Detector
detWall = surf(a/2,b/2,c*detHt - detHt + 2*rR0z,'FaceColor',[0.8 0.8 0.8],'LineStyle','none',...
'FaceLighting','flat','DiffuseStrength',0.7);
rotate(detWall,[0 1 0],90-phi,[0,0,2*rR0z]);
plot3([0 0],[0 0],[-0.9 0.1],'k','LineStyle','-.','LineWidth',1.6);
detEnd = fill3(cylRad*circlex,cylRad*circlez,0*circlez+2*rR0z-detHt,[0.5 0.5 0.5],'LineStyle','none',...
'FaceLighting','flat','DiffuseStrength',0.5,'SpecularStrength',0.5);
rotate(detEnd,[0 1 0],90-phi,[0,0,2*rR0z]);
frame = getframe(gcf);
writeVideo(vid,frame);
%hold off
end
% Output the movie as an mpg file
close(vid);