Cartoon showing mechanism behind bunch compression 

Matlab code 

Download matlab code

% Video cartoon of bunch compression in an XFEL

 

clear; close all;

 

vid = VideoWriter('bunchCompression.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);

 

myBlue = [0.4 0.44 0.73];

myCopper = [0.73 0.45 0.20];

 

LL = 10;

 

% Create a modulated cylinder that looks like a LINAC cavity

nCavs = 7; % Number of cavity units in LINAC

t = 0:pi/10:nCavs*2*pi;

r = 0.5+(0.1 + (sin(t/2)).^2).^0.25;

[x,y,z] = cylinder(r,50);

 

% Delete half the cavity to see wot's goin' on, loik

for ii = 141:-1:1

    for jj = 51:-1:1

        if (y(ii,jj)<0)

            x(ii,jj) = NaN;

            y(ii,jj) = NaN;

            z(ii,jj) = NaN;

        end

    end

end

 

viewAng = 20;

cavLength = 7; % Length of cavity

lChic = 7; % Length of chicane. 1 unit between cavity and chicane

lp = [7 5 4]; % Lighting direction

light('Position',lp,'Style','infinite');

 

nBunches = 84; % Number of bunches, each sort of representing a fuzzy electron

ebunchxPosTemp = 0.22*randn(nBunches,1); % Distribution of bunches in x-direction

ebunchxPos = sort(ebunchxPosTemp); % Distribution of bunches in x-direction, sorted

ebunchyPos = 0.05*randn(nBunches,1); % Distribution of bunches in y-direction

ebunchzPos = 0.05*randn(nBunches,1); % Distribution of bunches in z-direction

 

ebunchxEndPos = 0.02*randn(nBunches,1); % Small variation in end positions

% of bunches after bunch compression

 

M = 100; % Number of scatter points making up fuzzy cloud of bunch/electron

 

% Initialize rgb numbers

rcomp = zeros(nBunches,1);

gcomp = zeros(nBunches,1);

bcomp = zeros(nBunches,1);

 

nSteps = cavLength*20; % 20 steps per cavity unit

cavStep = cavLength/nSteps;

viewStep = 20/((cavLength+lChic+2)/cavStep);

 

for jj = 0:cavStep:cavLength

    viewAng = viewAng+viewStep; % Comment this out if you don't want to pan

    newplot

    hold on

    plot3([-1 cavLength+9.1], [-4 -4], [-4 -4],'LineWidth',0.1,'Color',[1 1 1]);

    plot3([-1 -1], [-2 -2], [-2 3],'LineWidth',0.1,'Color',[1 1 1]);

    cavity = surf(x,y,z*cavLength,'FaceAlpha',1,'FaceColor',myCopper,'LineStyle',...

        'none','FaceLighting','gouraud','DiffuseStrength',1);

    rotate(cavity,[0 1 0],90,[0,0,0]); % Transform from vertical to horizontal with

    % LINAC axis along the x-axis

 

    % Include arrows to indicate directions of magnetic fields in the chicane

    mArrow3([8.5 1 0],[8.5 -1 0],'color',myBlue,'stemWidth',0.1,...

        'tipWidth',0.2,'facealpha',0.5);

    mArrow3([10.5 -1 1.25],[10.5 1 1.25],'color',myBlue,'stemWidth',0.1,...

        'tipWidth',0.2,'facealpha',0.5);

    mArrow3([12.5 -1 1.25],[12.5 1 1.25],'color',myBlue,'stemWidth',0.1,...

        'tipWidth',0.2,'facealpha',0.5);

    mArrow3([14.5 1 0],[14.5 -1 0],'color',myBlue,'stemWidth',0.1,...

        'tipWidth',0.2,'facealpha',0.5);

 

    for ii = 1:nBunches

        % Create coordinates for scatter curve, fresh for each frame - this

        % provides small changes to the appearance of the electrons,

        % thereby adding an element of verisimilitude, dontchaknow

        ebunchx = 0.01*randn(M,1);

        ebunchy = 0.01*randn(M,1);

        ebunchz = 0.01*randn(M,1);

        % Determine the rgb components the electrons should have at the end

        % of the cavity

        for kk = 1:ceil(nBunches/2)

            rcomp(kk) = 0;

            gcomp(kk) = 2*kk/nBunches;

            bcomp(kk) = 1 - 2*kk/nBunches;

        end

        for kk = ceil(nBunches/2)+1:nBunches

            rcomp(kk) = 2*(kk-ceil(nBunches/2))/nBunches;

            gcomp(kk) = 1 - 2*(kk-ceil(nBunches/2))/nBunches;

            bcomp(kk) = 0;

        end

        % Determine the rgb components as the electrons move through the

        % cavity

        rcompnow = rcomp*jj/cavLength;

        gcompnow = 1 - (1-gcomp)*jj/cavLength;

        bcompnow = bcomp*jj/cavLength;

 

        % Plot out each bunch/electron

        ebunch(ii) = scatter3(ebunchx+ebunchxPos(ii)+jj,...

            ebunchy+ebunchyPos(ii),ebunchz+ebunchzPos(ii),2,...

            'filled','MarkerFaceColor',[rcompnow(ii) gcompnow(ii) bcompnow(ii)]);

        alpha = 0.7;

        set(ebunch(ii), 'MarkerEdgeAlpha',0,'MarkerFaceAlpha',alpha);

    end

 

    lp = [7 5 4];

    light('Position',lp,'Style','infinite');

    set(gca, 'Projection','perspective');

    set(gca,'View',[viewAng,10]);

    xlim([-1 LL]);

    ylim([-LL/2.5 LL/2.5]);

    zlim([-LL/2.5 LL/2.5]);

    axis off

    axis equal

    hold off

    frame = getframe(gcf);

    writeVideo(vid,frame);

end

 

% Move forward another 1 unit past end of cavity

 

for jj = cavStep:cavStep:1

    viewAng = viewAng+viewStep;

    newplot

    hold on

    plot3([-1 cavLength+9.1], [-4 -4], [-4 -4],'LineWidth',0.1,'Color',[1 1 1]);

    plot3([-1 -1], [-2 -2], [-2 3],'LineWidth',0.1,'Color',[1 1 1]);

    cavity = surf(x,y,z*cavLength,'FaceAlpha',1,'FaceColor',myCopper,'LineStyle',...

        'none','FaceLighting','gouraud','DiffuseStrength',1);

    rotate(cavity,[0 1 0],90,[0,0,0]);

 

    mArrow3([8.5 1 0],[8.5 -1 0],'color',myBlue,'stemWidth',0.1,...

        'tipWidth',0.2,'facealpha',0.5);

    mArrow3([10.5 -1 1.25],[10.5 1 1.25],'color',myBlue,'stemWidth',0.1,...

        'tipWidth',0.2,'facealpha',0.5);

    mArrow3([12.5 -1 1.25],[12.5 1 1.25],'color',myBlue,'stemWidth',0.1,...

        'tipWidth',0.2,'facealpha',0.5);

    mArrow3([14.5 1 0],[14.5 -1 0],'color',myBlue,'stemWidth',0.1,...

        'tipWidth',0.2,'facealpha',0.5);

 

    % Time to plot those babes

    for ii = 1:nBunches

        ebunch(ii) = scatter3(ebunchx+ebunchxPos(ii)+cavLength+jj,...

            ebunchy+ebunchyPos(ii),ebunchz+ebunchzPos(ii),2,...

            'filled','MarkerFaceColor',[rcompnow(ii) gcompnow(ii) bcompnow(ii)]);

        alpha = 0.7;

        set(ebunch(ii), 'MarkerEdgeAlpha',0,'MarkerFaceAlpha',alpha);

    end

 

    % Visual/image fluff

    lp = [7 5 4];

    light('Position',lp,'Style','infinite');

    set(gca, 'Projection','perspective');

    set(gca,'View',[viewAng,10]);

    xlim([-1 LL]);

    ylim([-LL/2.5 LL/2.5]);

    zlim([-LL/2.5 LL/2.5]);

    axis off

    axis equal

    hold off

    frame = getframe(gcf);

    writeVideo(vid,frame);

end

 

% Execute curved path through chicane

 

ampRed = 0.9; % Amplitude of curved path for lowest-energy bunch

ampBlue = 0.64; % Amplitude of curved path for highest-energy bunch

% Trace that follows electrons for guide to the eye

xTrace = 0:cavStep:lChic;

yTrace = 0.0*xTrace-0.001;

redTrace = -ampRed*cos(2*pi*xTrace/lChic)+ampRed/2;

blueTrace = -ampBlue*cos(2*pi*xTrace/lChic)+ampBlue/2;

 

for  jj = cavStep:cavStep:lChic

    viewAng = viewAng+viewStep;

    newplot

    hold on

    plot3([-1 cavLength+9.1], [-4 -4], [-4 -4],'LineWidth',0.1,'Color',[1 1 1]);

    plot3([-1 -1], [-2 -2], [-2 3],'LineWidth',0.1,'Color',[1 1 1]);

    cavity = surf(x,y,z*cavLength,'FaceAlpha',1,'FaceColor',myCopper,'LineStyle',...

        'none','FaceLighting','gouraud','DiffuseStrength',1);

    rotate(cavity,[0 1 0],90,[0,0,0]);

 

    % Magnetic-field arrows

    mArrow3([8.5 1 0],[8.5 -1 0],'color',myBlue,'stemWidth',0.1,...

        'tipWidth',0.2,'facealpha',0.5);

    mArrow3([10.5 -1 1.25],[10.5 1 1.25],'color',myBlue,'stemWidth',0.1,...

        'tipWidth',0.2,'facealpha',0.5);

    mArrow3([12.5 -1 1.25],[12.5 1 1.25],'color',myBlue,'stemWidth',0.1,...

        'tipWidth',0.2,'facealpha',0.5);

    mArrow3([14.5 1 0],[14.5 -1 0],'color',myBlue,'stemWidth',0.1,...

        'tipWidth',0.2,'facealpha',0.5);

 

    % Plot out path of low- and high-energy electrons through chicane

    if (jj>=0.25)

        redTracePlot = plot3(cavLength+1+xTrace(1:round(1+(jj-0.25)/cavStep)),...

            yTrace(1:round(1+(jj-0.25)/cavStep)),...

            ampRed/2+redTrace(1:round(1+(jj-0.25)/cavStep)),...

            'LineWidth',4,'Color',[1 0 0]);

        redTracePlot.Color(4) = 0.25;

        blueTracePlot = plot3(cavLength+1+xTrace(1:round(1+(jj-0.25)/cavStep)),...

            yTrace(1:round(1+(jj-0.25)/cavStep)),...

            ampBlue/2+blueTrace(1:round(1+(jj-0.25)/cavStep)),...

            'LineWidth',4,'Color',[0 0 1]);

        blueTracePlot.Color(4) = 0.25;

 

    end

    for ii=1:nBunches

        posCavEnd = cavLength + ebunchxPos(ii); % Position of bunch at end of cavity

        % Amplitude of curve for each electron/bunch according to its

        % energy/position

        amp(ii) = ampBlue + (ampRed-ampBlue)*ii/nBunches;

        % Length of period from perspective of the electron. Close but not

        % identical to lChic

        Ltot(ii) = lChic-ebunchxPos(ii)+ebunchxEndPos(ii);

        % Now let's plot those suckers out!

        ebunch(ii) = scatter3(ebunchx+cavLength+1+... % Scatter coords + cavity length + 1 unit

            ebunchxPos(ii)*(1-jj/lChic)+ ... % Reduce initial scatter

            ebunchxEndPos(ii)*jj/lChic ... % Grow in final small variation in axial positions

            +jj, ... % Move one step forward

            ebunchy+ebunchyPos(ii), ...

            ebunchz+ebunchzPos(ii)-amp(ii)*cos(2*pi*jj/Ltot(ii))+amp(ii), ...

            2,'filled','MarkerFaceColor',...

            [rcompnow(ii) gcompnow(ii) bcompnow(ii)]);

        alpha = 0.7;

        set(ebunch(ii), 'MarkerEdgeAlpha',0,'MarkerFaceAlpha',alpha);

    end

    lp = [7 5 4];

    light('Position',lp,'Style','infinite');

    set(gca, 'Projection','perspective');

    set(gca,'View',[viewAng,10]);

    xlim([-1 LL]);

    ylim([-LL/2.5 LL/2.5]);

    zlim([-LL/2.5 LL/2.5]);

    axis off

    axis equal

    hold off

    frame = getframe(gcf);

    writeVideo(vid,frame);

end

 

% Move forward one final unit

 

for jj = cavStep:cavStep:1

    viewAng = viewAng+viewStep;

    newplot

    hold on

    plot3([-1 cavLength+9.1], [-4 -4], [-4 -4],'LineWidth',0.1,'Color',[1 1 1]);

    plot3([-1 -1], [-2 -2], [-2 3],'LineWidth',0.1,'Color',[1 1 1]);

    cavity = surf(x,y,z*cavLength,'FaceAlpha',1,'FaceColor',myCopper,'LineStyle',...

        'none','FaceLighting','gouraud','DiffuseStrength',1);

    rotate(cavity,[0 1 0],90,[0,0,0]);

 

    mArrow3([8.5 1 0],[8.5 -1 0],'color',myBlue,'stemWidth',0.1,...

        'tipWidth',0.2,'facealpha',0.5);

    mArrow3([10.5 -1 1.25],[10.5 1 1.25],'color',myBlue,'stemWidth',0.1,...

        'tipWidth',0.2,'facealpha',0.5);

    mArrow3([12.5 -1 1.25],[12.5 1 1.25],'color',myBlue,'stemWidth',0.1,...

        'tipWidth',0.2,'facealpha',0.5);

    mArrow3([14.5 1 0],[14.5 -1 0],'color',myBlue,'stemWidth',0.1,...

        'tipWidth',0.2,'facealpha',0.5);

    % Finish off trace curves

    if (jj<0.25)

        endIndex = round((lChic+(jj-0.25))/cavStep);

        redTracePlot = plot3(cavLength+1+xTrace(1:endIndex),...

            yTrace(1:endIndex),...

            ampRed/2+redTrace(1:endIndex),...

            'LineWidth',4,'Color',[1 0 0]);

        redTracePlot.Color(4) = 0.25;

        blueTracePlot = plot3(cavLength+1+xTrace(1:endIndex),...

            yTrace(1:endIndex),...

            ampBlue/2+blueTrace(1:endIndex),...

            'LineWidth',4,'Color',[0 0 1]);

        blueTracePlot.Color(4) = 0.25;

    else

        redTracePlot = plot3(cavLength+1+xTrace,...

            yTrace,...

            ampRed/2+redTrace,...

            'LineWidth',4,'Color',[1 0 0]);

        redTracePlot.Color(4) = 0.25;

        blueTracePlot = plot3(cavLength+1+xTrace,...

            yTrace,...

            ampBlue/2+blueTrace,...

            'LineWidth',4,'Color',[0 0 1]);

        blueTracePlot.Color(4) = 0.25;

    end

 

    for ii = 1:nBunches

        ebunch(ii) = scatter3(ebunchx+cavLength+1+ebunchxEndPos(ii)+lChic+jj,...

            ebunchy+ebunchyPos(ii),ebunchz+ebunchzPos(ii),2,...

            'filled','MarkerFaceColor',[rcompnow(ii) gcompnow(ii) bcompnow(ii)]);

        alpha = 0.7;

        set(ebunch(ii), 'MarkerEdgeAlpha',0,'MarkerFaceAlpha',alpha);

    end

    lp = [7 5 4];

    light('Position',lp,'Style','infinite');

    set(gca, 'Projection','perspective');

    set(gca,'View',[viewAng,10]); % Set 'viewAng' to a constant, e.g. 20 if you don't want to pan

    xlim([-1 LL]);

    ylim([-LL/2.5 LL/2.5]);

    zlim([-LL/2.5 LL/2.5]);

    axis off

    axis equal

    hold off

    frame = getframe(gcf);

    writeVideo(vid,frame);

end

 

% Output the movie as an mpg file

close(vid);