Scanning transmission x-ray microscopy experiment cartoon 

Matlab code 

% Movie cartoon of a scanning STXM experiment

% NEXAFS data for two different polymer types lifted using "GRABIT" from

% the paper "Simultaneous Surface and Bulk Imaging of Polymer Blends with

% X-ray Spectromicroscopy" by C.R. McNeill and B. Watts, Macromol. Rapid

% Commun. vol 31, pp 1706-1712 (2010). Image of polymer film likewise from

% the same article. The data for F8BT was changed to include an absorption

% maximum at ca 284.3 eV in order to better show the difference in "colour"

% of the two polymer types.

 

clear all; close all

vid = VideoWriter('stxmExpt.mp4','MPEG-4');

vid.Quality = 100;

vid.FrameRate = 60;

open(vid);

figure('units','pixels','position',[0 0 1920 1080],'ToolBar','none');

set(0,'defaultfigurecolor',[1 1 1]);

 

s2fzp = 3; % Source to FZP distance

s2sample = 3.5; % Source to sample distance

s2det = 4; % Source to detector distance

sampleSize = 0.5; % Half-width of sample size

 

myBlue = [0.4 0.44 0.73];

lp = [-2 -1 1];

view(-44,10);

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

 

% Some physical properties of the polymer film

muPFB = 9.5e4; % mass attenuation coefficient in cm2/g of PFB @ 285.1 eV

muF8BT = 3.65e4; % mass attenuation coefficient in cm2/g of F8BT @ 285.1 eV

filmTh = 1.5e-5; % Average film thickness in cm

 

% Import raw PFB transmission data gleaned from paper using "GRABIT" and

% interpolate to 0.02 eV steps. Max value is normalized to 1.0

PFBdata = importdata('PFB.txt');

xx = PFBdata(:,1);

yy = PFBdata(:,2);

xintp = 283:0.02:287; % Photon energy range in 20 meV steps

yintp1 = interp1(xx,yy,xintp,'spline');

 

% ... and again for F8BT polymer. On same scale as PFB data (i.e. not normalized)

F8BTdata = importdata('F8BT.txt');

xx = F8BTdata(:,1);

yy = F8BTdata(:,2);

yintp2 = interp1(xx,yy,xintp,'spline');

 

% Read in image files

origIm = imread('polymerFilm2.png'); % Original transmission image

stxmMap = imread('polymerFilm.png'); % Red version size 1000 x 1000 pixels

bw50x50 = imread('polymerFilmBW_50x50.jpg'); % BW version pixelated to 50 x 50

% Calibrate this to known min and max transmissions for 150 nm film and at

% 285.1 eV to yield transmission values between 0.0 and 1.0

% maxTrans = 0.60; % Transmission for 100% F8BT

% minTrans = 0.235; % Transmission for 100% PFB

maxTrans = 0.98; % Transmission for 100% F8BT

minTrans = 0.04; % Transmission for 100% PFB

bw50x50cal = im2double(bw50x50)*(maxTrans-minTrans) + minTrans;

% Calculate fraction of PFB for each pixel probed in 50x50 array using

% equation Transm = 0.235x + 0.60(1-x). x = fracPFB

fracPFB = (maxTrans-bw50x50cal)/(maxTrans-minTrans);

 

grBl = imread('greenBlue.tiff');

 

% Locations and sizes of subplots

pos1 = [0.1 0.01 0.7 0.58];

pos2 = [0.2 0.6 0.3 0.34];

pos3 = [0.56 0.59 0.355*9/16 0.355];

 

% Initialize blank image for developing STXM map

blankIm = zeros(size(stxmMap,1),size(stxmMap,2),size(stxmMap,3),'uint8');

 

% Scan loops along rows and down columns

 

for row = 1:50 % 50 sampling points wide

    for col = 1:50 % 25 sampling points high

        if (round(row/2) == row/2) % Map developing to the left

            mapXpos = 50-col+1;

        else % Map developing to the right

            mapXpos = col;

        end

        

        if (col <= 25) && (row == 1) % For the first 25 pixels show energy scan

            for escan = 1:3:201 % Loop to plot out scan and change radiation colour

                hold off

                subplot('position',pos1);

                newplot

                % Color of radiation

                if (escan <= 100)

                    rcomp = 0;

                    gcomp = (101-escan)/100;

                    bcomp = escan/100;

                else

                    rcomp = (escan-100)/101;

                    gcomp = 0;

                    bcomp = 1;

                end

                radcol = [rcomp gcomp bcomp];

                % Diverging radiation from source to FZP

                t = 0:1;

                r = t;

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

                srcRad = surf(0.2*x,0.2*y,s2fzp*z-escan/3000,...

                    'FaceAlpha',0.35,'FaceColor',radcol,'LineStyle',...

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

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

                

                hold on

                

                % FZP

                FZPth = 0:pi/100:2*pi;

                imax = 14;

                for jj = imax:-2:1

                    r1 = 0.055*(jj)^0.5;

                    r2 = 0.055*(jj-1)^0.5;

                    z_circle1 = r1*cos(FZPth);

                    y_circle1 = r1*sin(FZPth);

                    x_circle1 = 0.0*y_circle1;

                    z_circle2 = r2*cos(FZPth);

                    y_circle2 = r2*sin(FZPth);

                    x_circle2 = 0.0*y_circle2;

                    z_circle = [z_circle1 z_circle2];

                    y_circle = [y_circle1 y_circle2];

                    x_circle = [x_circle1 x_circle2];

                    zone = fill3(x_circle+s2fzp-escan/3000,y_circle,z_circle,...

                        'k','LineStyle','none');

                end

                

                % Converging radiation from FZP to sample

                convRad = surf(0.2*x+s2sample,0.2*y,-(s2sample-s2fzp+escan/3000)*z,...

                    'FaceAlpha',0.35,'FaceColor',radcol,'LineStyle',...

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

                rotate(convRad,[0 1 0],90,[s2sample,0,0]);

                

                % Thin polymer film sample

                if (round(row/2) == row/2) % Move film to right

                    filmXpos = 0.5+1/100-(col)/50;

                else % Move film to the left

                    filmXpos = -0.5-1/100+col/50;

                end

                filmYpos = (-25+row)/50-1/100;

                

                XX = [0 0; 0 0]+s2sample;

                YY = [1 -1; 1 -1]*sampleSize+filmXpos;

                ZZ = [1 1;-1 -1]*sampleSize+filmYpos;

                sample = surf(XX,YY,ZZ,origIm,'FaceColor','texturemap','EdgeColor','none');

                alpha(sample,0.5);

                sample2 = surf(XX+0.01,YY,ZZ,origIm,'FaceColor','texturemap','EdgeColor','none');

                alpha(sample2,0.5);

                % Dummy horizontal and vertical lines to stop image resizing

                dl1 = plot3([0 0],[-1 1],[0 0],...

                    'color','w', 'LineWidth', 0.1);

                dl1.Color(4) = 0.0;

                dl2 = plot3([0 0],[0 0],[-1 1],...

                    'color','w', 'LineWidth', 0.1);

                dl2.Color(4) = 0.0;

                dl3 = plot3([0 s2det+0.5],[0 0],[0 0],...

                    'color','w', 'LineWidth', 0.1);

                dl3.Color(4) = 0.0;

                

                expnt = (muPFB*fracPFB(row,mapXpos)*yintp1 + ...

                    muF8BT*(1-fracPFB(row,mapXpos))*yintp2)*filmTh;

                Tr = exp(-expnt);

                

                % Diverging radiation from sample to energy-dispersive detector

                convRad2 = surf(0.2*x+s2sample,0.2*y,(s2det-s2sample)*z,...

                    'FaceAlpha',0.35*mean(Tr),'FaceColor',radcol,'LineStyle',...

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

                rotate(convRad2,[0 1 0],90,[s2sample,0,0]);

                

                % Bright spot on sample

                spot = 0:pi/45:2*pi;

                aa = 0.005*cos(spot);

                bb = 0.005*sin(spot);

                cc = 0.0*aa;

                fill3(cc+s2sample-0.001,bb,aa,'y','LineStyle','none','FaceAlpha',0.7,...

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

                fill3(cc*2+s2sample-0.0005,bb*2,aa*2,'y','LineStyle','none','FaceAlpha',0.35,...

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

                fill3(cc*3+s2sample-0.00025,bb*3,aa*3,'y','LineStyle','none','FaceAlpha',0.15,...

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

                

                % Create detector

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

                detBody = surf(x/4+s2det,y/4,z/2,'FaceColor',[0.5 0.5 0.5],'LineStyle',...

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

                rotate(detBody,[0 1 0],90,[s2det,0,0]);

                detFaceTh = 0:pi/45:2*pi;

                aa = cos(detFaceTh);

                bb = sin(detFaceTh);

                cc = 0.0*aa;

                detFace = fill3(cc+s2det,aa/4,bb/4,myBlue,'LineStyle',...

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

                

                axis off

                axis equal

                %                 axis tight

                xlim([-0.05 s2det+0.55]);

                ylim([-1.05 1.05]);

                zlim([-1.05 1.05]);

                

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

                view(-44,10);

                

                % *************************************************************

                % Plot x-ray transmission curve

                hold off

                subplot('position',pos2);

                newplot

                expnt = (muPFB*fracPFB(row,mapXpos)*yintp1 + ...

                    muF8BT*(1-fracPFB(row,mapXpos))*yintp2)*filmTh;

                Tr = exp(-expnt);

                plot(xintp(1:escan),Tr(1:escan),'color','r', 'LineWidth', 2.0)

                xlim([min(xintp) max(xintp)]);

                ylim([0.0 1.0]);

                axl = get(gca,'XTickLabel');

                set(gca,'XTickLabel',axl,'FontName','Helvetica','fontsize',18);

                set(gca,'TickLength',[0.02, 1]);

                set(gca,'linewidth',2);

                xlabel('Photon energy [eV]');

                ylabel('Transmission');

                

                hold off

                % *****************************************************************

                % Plot developing STXM image

                hold off

                subplot('position',pos3);

                newplot

                if (round(row/2) == row/2) % Map developing to the left

                    mapXpos = 50-col+1;

                else % Map developing to the right

                    mapXpos = col;

                end

                mapYpos = row;

                stcol = 20*(mapXpos-1)+1;

                endcol = 20*mapXpos;

                strow = 20*(row-1)+1;

                endrow = 20*row;

                blankIm(strow:endrow,stcol:endcol,1:3) = stxmMap(strow:endrow,stcol:endcol,1:3);

                imshow(blankIm)

                

                frame = getframe(gcf);

                writeVideo(vid,frame);

            end % End of slow loops for first 25 pixels in row 1

            

            

        else % Fast recording showing only final transmission curve for each sample position

            

            

            radcol = [0 0 1];

            hold off

            subplot('position',pos1);

            newplot

            

            % Diverging radiation from source to FZP

            t = 0:1;

            r = t;

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

            grBl = imread('greenBlue.tiff');

            grBl = imrotate(grBl,-90);

            srcRad = surf(0.2*x,0.2*y,s2fzp*z-1/30,grBl,...

                'FaceAlpha',0.35,'FaceColor','texturemap','LineStyle',...

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

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

            

            hold on

            

            % FZP

            FZPth = 0:pi/100:2*pi;

            imax = 14;

            for jj = imax:-2:1

                r1 = 0.055*(jj)^0.5;

                r2 = 0.055*(jj-1)^0.5;

                z_circle1 = r1*cos(FZPth);

                y_circle1 = r1*sin(FZPth);

                x_circle1 = 0.0*y_circle1;

                z_circle2 = r2*cos(FZPth);

                y_circle2 = r2*sin(FZPth);

                x_circle2 = 0.0*y_circle2;

                z_circle = [z_circle1 z_circle2];

                y_circle = [y_circle1 y_circle2];

                x_circle = [x_circle1 x_circle2];

                zone = fill3(x_circle+s2fzp-1/30,y_circle,z_circle,...

                    'k','LineStyle','none');

            end

            

            % Converging radiation from FZP to sample

            blMa = imread('blueMauve.tiff');

            blMa = imrotate(blMa,90);

            convRad = surf(0.2*x+s2sample,0.2*y,-(s2sample-s2fzp+1/30)*z,blMa,...

                'FaceAlpha',0.35,'FaceColor','texturemap','LineStyle',...

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

            rotate(convRad,[0 1 0],90,[s2sample,0,0]);

            

            % Thin polymer film sample

            if (round(row/2) == row/2) % Move film to right

                filmXpos = 0.5+1/100-(col)/50;

            else % Move film to the left

                filmXpos = -0.5-1/100+col/50;

            end

            filmYpos = (-25+row)/50-1/100;

            

            XX = [0 0; 0 0]+s2sample;

            YY = [1 -1; 1 -1]*sampleSize+filmXpos;

            ZZ = [1 1;-1 -1]*sampleSize+filmYpos;

            sample = surf(XX,YY,ZZ,origIm,'FaceColor','texturemap','EdgeColor','none');

            alpha(sample,0.5);

            sample2 = surf(XX+0.01,YY,ZZ,origIm,'FaceColor','texturemap','EdgeColor','none');

            alpha(sample2,0.5);

            % Dummy horizontal and vertical lines to stop image resizing

            dl1 = plot3([0 0],[-1 1],[0 0],...

                'color','w', 'LineWidth', 0.1);

            dl1.Color(4) = 0.0;

            dl2 = plot3([0 0],[0 0],[-1 1],...

                'color','w', 'LineWidth', 0.1);

            dl2.Color(4) = 0.0;

            dl3 = plot3([0 s2det+0.5],[0 0],[0 0],...

                'color','w', 'LineWidth', 0.1);

            dl3.Color(4) = 0.0;

            

            % Diverging radiation from sample to energy-dispersive detector

            expnt = (muPFB*fracPFB(row,mapXpos)*yintp1 + ...

                muF8BT*(1-fracPFB(row,mapXpos))*yintp2)*filmTh;

            Tr = exp(-expnt);

            maPu = imread('mauvePurple.tiff');

            maPu = imrotate(maPu,-90);

            convRad2 = surf(0.2*x+s2sample,0.2*y,(s2det-s2sample)*z,maPu,...

                'FaceAlpha',0.35*mean(Tr),'FaceColor','texturemap','LineStyle',...

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

            rotate(convRad2,[0 1 0],90,[s2sample,0,0]);

            

            % Bright spot on sample

            spot = 0:pi/45:2*pi;

            aa = 0.005*cos(spot);

            bb = 0.005*sin(spot);

            cc = 0.0*aa;

            fill3(cc+s2sample-0.001,bb,aa,'y','LineStyle','none','FaceAlpha',0.7,...

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

            fill3(cc*2+s2sample-0.0005,bb*2,aa*2,'y','LineStyle','none','FaceAlpha',0.35,...

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

            fill3(cc*3+s2sample-0.00025,bb*3,aa*3,'y','LineStyle','none','FaceAlpha',0.15,...

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

            

            % Create detector

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

            detBody = surf(x/4+s2det,y/4,z/2,'FaceColor',[0.5 0.5 0.5],'LineStyle',...

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

            rotate(detBody,[0 1 0],90,[s2det,0,0]);

            detFaceTh = 0:pi/45:2*pi;

            aa = cos(detFaceTh);

            bb = sin(detFaceTh);

            cc = 0.0*aa;

            detFace = fill3(cc+s2det,aa/4,bb/4,myBlue,'LineStyle',...

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

            

            axis off

            axis equal

            %                 axis tight

            xlim([-0.05 s2det+0.55]);

            ylim([-1.05 1.05]);

            zlim([-1.05 1.05]);

            

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

            view(-44,10);

            

            % *************************************************************

            % Plot x-ray transmission curve

            hold off

            subplot('position',pos2);

            newplot

            expnt = (muPFB*fracPFB(row,mapXpos)*yintp1 + ...

                muF8BT*(1-fracPFB(row,mapXpos))*yintp2)*filmTh;

            Tr = exp(-expnt);

            plot(xintp,Tr,'color','r', 'LineWidth', 2.0)

            xlim([min(xintp) max(xintp)]);

            ylim([0.0 1.0]);

            axl = get(gca,'XTickLabel');

            set(gca,'XTickLabel',axl,'FontName','Helvetica','fontsize',18);

            set(gca,'TickLength',[0.02, 1]);

            set(gca,'linewidth',2);

            xlabel('Photon energy [eV]');

            ylabel('Transmission');

            

            hold off

            % *****************************************************************

            % Plot developing STXM image

            hold off

            subplot('position',pos3);

            newplot

            if (round(row/2) == row/2) % Map developing to the left

                mapXpos = 50-col+1;

            else % Map developing to the right

                mapXpos = col;

            end

            mapYpos = row;

            stcol = 20*(mapXpos-1)+1;

            endcol = 20*mapXpos;

            strow = 20*(row-1)+1;

            endrow = 20*row;

            blankIm(strow:endrow,stcol:endcol,1:3) = stxmMap(strow:endrow,stcol:endcol,1:3);

            imshow(blankIm)

            

            frame = getframe(gcf);

            writeVideo(vid,frame);

        end

        

        

    end

end

 

% Output the movie as an mpg file

close(vid);