Major folder renaming.
This commit is contained in:
parent
bb3ae4192a
commit
e83af75e1d
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,5 +6,6 @@ ULE Cavity Characteristics/Figures
|
|||||||
*.h5
|
*.h5
|
||||||
*.png
|
*.png
|
||||||
*.pyc
|
*.pyc
|
||||||
|
*.mat
|
||||||
.ipynb_checkpoints/
|
.ipynb_checkpoints/
|
||||||
.vscode/
|
.vscode/
|
@ -1,36 +0,0 @@
|
|||||||
classdef PhysicsConstants < handle
|
|
||||||
properties (Constant)
|
|
||||||
% CODATA
|
|
||||||
PlanckConstant=6.62607015E-34;
|
|
||||||
PlanckConstantReduced=6.62607015E-34/(2*pi);
|
|
||||||
FineStructureConstant=7.2973525698E-3;
|
|
||||||
ElectronMass=9.10938291E-31;
|
|
||||||
GravitationalConstant=6.67384E-11;
|
|
||||||
ProtonMass=1.672621777E-27;
|
|
||||||
AtomicMassUnit=1.660539066E-27;
|
|
||||||
BohrRadius=5.2917721067E-11;
|
|
||||||
BohrMagneton=9.274009994E-24;
|
|
||||||
BoltzmannConstant=1.38064852E-23;
|
|
||||||
StandardGravityAcceleration=9.80665;
|
|
||||||
SpeedOfLight=299792458;
|
|
||||||
StefanBoltzmannConstant=5.670373E-8;
|
|
||||||
ElectronCharge=1.602176634E-19;
|
|
||||||
VacuumPermeability=1.25663706212E-6;
|
|
||||||
DielectricConstant=8.8541878128E-12;
|
|
||||||
ElectronGyromagneticFactor=-2.00231930436153;
|
|
||||||
AvogadroConstant=6.02214076E23;
|
|
||||||
ZeroKelvin = 273.15;
|
|
||||||
GravitationalAcceleration = 9.80553;
|
|
||||||
|
|
||||||
% Dy specific constants
|
|
||||||
Dy164Mass = 163.929174751*1.660539066E-27;
|
|
||||||
Dy164IsotopicAbundance = 0.2826;
|
|
||||||
DyMagneticMoment = 9.93*9.274009994E-24;
|
|
||||||
end
|
|
||||||
|
|
||||||
methods
|
|
||||||
function pc = PhysicsConstants()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,68 +0,0 @@
|
|||||||
classdef ProgressBar < handle
|
|
||||||
% class for command-line progress-bar notification.
|
|
||||||
properties
|
|
||||||
strPercentageLength;
|
|
||||||
strDotsMaximum;
|
|
||||||
end
|
|
||||||
methods
|
|
||||||
%--- constructor
|
|
||||||
function this = ProgressBar()
|
|
||||||
%% Initialization
|
|
||||||
% Vizualization parameters
|
|
||||||
this.strPercentageLength = 10; % Length of percentage string (must be >5)
|
|
||||||
this.strDotsMaximum = 10; % The total number of dots in a progress bar
|
|
||||||
end
|
|
||||||
%--- print method
|
|
||||||
function run(this, msg)
|
|
||||||
% This function creates a text progress bar. It should be called with a
|
|
||||||
% STRING argument to initialize and terminate. Otherwise the number corresponding
|
|
||||||
% to progress in % should be supplied.
|
|
||||||
% INPUTS: C Either: Text string to initialize or terminate
|
|
||||||
% Percentage number to show progress
|
|
||||||
% OUTPUTS: N/A
|
|
||||||
% Example: Please refer to demo_textprogressbar.m
|
|
||||||
% Author: Paul Proteus (e-mail: proteus.paul (at) yahoo (dot) com)
|
|
||||||
% Version: 1.0
|
|
||||||
% Changes tracker: 29.06.2010 - First version
|
|
||||||
% Inspired by: http://blogs.mathworks.com/loren/2007/08/01/monitoring-progress-of-a-calculation/
|
|
||||||
%% Main
|
|
||||||
persistent strCR; % Carriage return pesistent variable
|
|
||||||
if isempty(strCR) && ~ischar(msg)
|
|
||||||
% Progress bar must be initialized with a string
|
|
||||||
error('The text progress must be initialized with a string!');
|
|
||||||
elseif isempty(strCR) && ischar(msg)
|
|
||||||
% Progress bar - initialization
|
|
||||||
fprintf('%s',msg);
|
|
||||||
strCR = -1;
|
|
||||||
elseif ~isempty(strCR) && ischar(msg)
|
|
||||||
% Progress bar - termination
|
|
||||||
strCR = [];
|
|
||||||
fprintf([msg '\n']);
|
|
||||||
elseif isnumeric(msg)
|
|
||||||
% Progress bar - normal progress
|
|
||||||
msg = floor(msg);
|
|
||||||
percentageOut = [num2str(msg) '%%'];
|
|
||||||
percentageOut = [percentageOut repmat(' ',1,this.strPercentageLength-length(percentageOut)-1)];
|
|
||||||
nDots = floor(msg/100*this.strDotsMaximum);
|
|
||||||
dotOut = ['[' repmat('.',1,nDots) repmat(' ',1,this.strDotsMaximum-nDots) ']'];
|
|
||||||
strOut = [percentageOut dotOut];
|
|
||||||
|
|
||||||
% Print it on the screen
|
|
||||||
if strCR == -1
|
|
||||||
% Don't do carriage return during first run
|
|
||||||
fprintf(strOut);
|
|
||||||
else
|
|
||||||
% Do it during all the other runs
|
|
||||||
fprintf([strCR strOut]);
|
|
||||||
end
|
|
||||||
|
|
||||||
% Update carriage return
|
|
||||||
strCR = repmat('\b',1,length(strOut)-1);
|
|
||||||
|
|
||||||
else
|
|
||||||
% Any other unexpected input
|
|
||||||
error('Unsupported argument type');
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,6 +0,0 @@
|
|||||||
function CellOut = convertstruct2cell(StructIn)
|
|
||||||
% CellOut = Convertstruct2cell(StructIn)
|
|
||||||
% converts a struct into a cell-matrix where the first column contains
|
|
||||||
% the fieldnames and the second the contents
|
|
||||||
CellOut = [fieldnames(StructIn) struct2cell(StructIn)]';
|
|
||||||
end
|
|
@ -1,85 +0,0 @@
|
|||||||
function makeMovie(run_index)
|
|
||||||
set(0,'defaulttextInterpreter','latex')
|
|
||||||
set(groot, 'defaultAxesTickLabelInterpreter','latex'); set(groot, 'defaultLegendInterpreter','latex');
|
|
||||||
|
|
||||||
folder_path = './Data';
|
|
||||||
|
|
||||||
FileDir = dir(sprintf(horzcat(folder_path, '/Run_%03i/*.mat'),run_index));
|
|
||||||
NumFiles = numel(FileDir);
|
|
||||||
|
|
||||||
Data = load(sprintf(horzcat(folder_path, '/Run_%03i/psi_%i.mat'),run_index,1),'Params','Transf');
|
|
||||||
|
|
||||||
Params = Data.Params;
|
|
||||||
Transf = Data.Transf;
|
|
||||||
|
|
||||||
x = Transf.x; y = Transf.y; z = Transf.z;
|
|
||||||
dx = x(2)-x(1); dy = y(2)-y(1); dz = z(2)-z(1);
|
|
||||||
|
|
||||||
mkdir(sprintf(horzcat(folder_path, '/Run_%03i/Figures'),run_index))
|
|
||||||
outputVideo = VideoWriter(fullfile(horzcat(folder_path, '/Movie.avi')));
|
|
||||||
outputVideo.FrameRate = 10;
|
|
||||||
open(outputVideo)
|
|
||||||
|
|
||||||
figure(1);
|
|
||||||
x0 = 800;
|
|
||||||
y0 = 200;
|
|
||||||
width = 800;
|
|
||||||
height = 600;
|
|
||||||
set(gcf,'position',[x0,y0,width,height])
|
|
||||||
|
|
||||||
for ii = 1:(NumFiles-1)
|
|
||||||
Data = load(sprintf(horzcat(folder_path, '/Run_%03i/psi_%i.mat'),run_index,ii),'psi','muchem','T','Observ');
|
|
||||||
|
|
||||||
psi = Data.psi;
|
|
||||||
muchem = Data.muchem;
|
|
||||||
T = Data.T;
|
|
||||||
Observ = Data.Observ;
|
|
||||||
|
|
||||||
%Plotting
|
|
||||||
subplot(2,3,1)
|
|
||||||
n = abs(psi).^2;
|
|
||||||
nxz = squeeze(trapz(n*dy,2));
|
|
||||||
nyz = squeeze(trapz(n*dx,1));
|
|
||||||
nxy = squeeze(trapz(n*dz,3));
|
|
||||||
|
|
||||||
plotxz = pcolor(x,z,nxz'); shading interp
|
|
||||||
set(plotxz, 'EdgeColor', 'none');
|
|
||||||
xlabel('$x$ [$\mu$m]'); ylabel('$z$ [$\mu$m]');
|
|
||||||
|
|
||||||
subplot(2,3,2)
|
|
||||||
plotyz = pcolor(y,z,nyz'); shading interp
|
|
||||||
set(plotyz, 'EdgeColor', 'none');
|
|
||||||
xlabel('$y$ [$\mu$m]'); ylabel('$z$ [$\mu$m]');
|
|
||||||
|
|
||||||
subplot(2,3,3)
|
|
||||||
plotxy = pcolor(x,y,nxy'); shading interp
|
|
||||||
set(plotxy, 'EdgeColor', 'none');
|
|
||||||
xlabel('$x$ [$\mu$m]'); ylabel('$y$ [$\mu$m]');
|
|
||||||
|
|
||||||
subplot(2,3,4)
|
|
||||||
plot(Observ.tVecPlot*1000/Params.w0,Observ.NormVec,'-b')
|
|
||||||
ylabel('Normalization'); xlabel('$t$ [$m$s]');
|
|
||||||
|
|
||||||
subplot(2,3,5)
|
|
||||||
plot(Observ.tVecPlot*1000/Params.w0,1-2*Observ.PCVec/pi,'-b')
|
|
||||||
ylabel('Coherence'); xlabel('$t$ [$m$s]');
|
|
||||||
ylim([0,1])
|
|
||||||
|
|
||||||
subplot(2,3,6)
|
|
||||||
plot(Observ.tVecPlot*1000/Params.w0,Observ.EVec,'-b')
|
|
||||||
ylabel('E'); xlabel('$t$ [$m$s]');
|
|
||||||
|
|
||||||
tVal = Observ.tVecPlot(end)*1000/Params.w0;
|
|
||||||
sgtitle(sprintf('$\\mu =%.3f \\hbar\\omega_0$, $T=%.1f$nK, $t=%.1f$ms',muchem,T,tVal))
|
|
||||||
|
|
||||||
drawnow
|
|
||||||
saveas(gcf,sprintf(horzcat(folder_path, '/Run_%03i/Figures/Image_%i.jpg'),run_index,ii))
|
|
||||||
img = imread(sprintf(horzcat(folder_path, '/Run_%03i/Figures/Image_%i.jpg'),run_index,ii));
|
|
||||||
writeVideo(outputVideo,img)
|
|
||||||
clf
|
|
||||||
end
|
|
||||||
|
|
||||||
close(outputVideo)
|
|
||||||
close(figure(1))
|
|
||||||
delete(sprintf(horzcat(folder_path, '/Run_%03i/Figures/*.jpg'),run_index)) % deleting images after movie is made
|
|
||||||
end
|
|
@ -1,44 +0,0 @@
|
|||||||
function plotLive(psi,Params,Transf,Observ)
|
|
||||||
set(0,'defaulttextInterpreter','latex')
|
|
||||||
set(groot, 'defaultAxesTickLabelInterpreter','latex'); set(groot, 'defaultLegendInterpreter','latex');
|
|
||||||
|
|
||||||
format long
|
|
||||||
x = Transf.x*Params.l0*1e6;
|
|
||||||
y = Transf.y*Params.l0*1e6;
|
|
||||||
z = Transf.z*Params.l0*1e6;
|
|
||||||
dx = x(2)-x(1); dy = y(2)-y(1); dz = z(2)-z(1);
|
|
||||||
|
|
||||||
%Plotting
|
|
||||||
|
|
||||||
subplot(2,3,1)
|
|
||||||
n = abs(psi).^2;
|
|
||||||
nxz = squeeze(trapz(n*dy,2));
|
|
||||||
nyz = squeeze(trapz(n*dx,1));
|
|
||||||
nxy = squeeze(trapz(n*dz,3));
|
|
||||||
|
|
||||||
plotxz = pcolor(x,z,nxz');
|
|
||||||
set(plotxz, 'EdgeColor', 'none');
|
|
||||||
xlabel('$x$ [$\mu$m]'); ylabel('$z$ [$\mu$m]');
|
|
||||||
|
|
||||||
subplot(2,3,2)
|
|
||||||
plotyz = pcolor(y,z,nyz');
|
|
||||||
set(plotyz, 'EdgeColor', 'none');
|
|
||||||
xlabel('$y$ [$\mu$m]'); ylabel('$z$ [$\mu$m]');
|
|
||||||
|
|
||||||
subplot(2,3,3)
|
|
||||||
plotxy = pcolor(x,y,nxy');
|
|
||||||
set(plotxy, 'EdgeColor', 'none');
|
|
||||||
xlabel('$x$ [$\mu$m]'); ylabel('$y$ [$\mu$m]');
|
|
||||||
|
|
||||||
subplot(2,3,4)
|
|
||||||
plot(-log10(Observ.residual),'-b')
|
|
||||||
ylabel('$-\mathrm{log}_{10}(r)$'); xlabel('steps');
|
|
||||||
|
|
||||||
subplot(2,3,5)
|
|
||||||
plot(Observ.EVec,'-b')
|
|
||||||
ylabel('$E$'); xlabel('steps');
|
|
||||||
|
|
||||||
subplot(2,3,6)
|
|
||||||
plot(Observ.mucVec,'-b')
|
|
||||||
ylabel('$\mu$'); xlabel('steps');
|
|
||||||
end
|
|
@ -1,94 +0,0 @@
|
|||||||
function visualizeDDIPotential(Transf)
|
|
||||||
|
|
||||||
x = Transf.x;
|
|
||||||
y = Transf.y;
|
|
||||||
z = Transf.z;
|
|
||||||
|
|
||||||
[X,Y] = meshgrid(x,y);
|
|
||||||
|
|
||||||
height = 20;
|
|
||||||
width = 45;
|
|
||||||
figure(1)
|
|
||||||
clf
|
|
||||||
set(gcf, 'Units', 'centimeters')
|
|
||||||
set(gcf, 'Position', [2 4 width height])
|
|
||||||
set(gcf, 'PaperPositionMode', 'auto')
|
|
||||||
|
|
||||||
subplot(1,2,1)
|
|
||||||
zlin = ones(size(X, 1)) * z(1); % Generate z data
|
|
||||||
mesh(x, y, zlin, 'EdgeColor','b') % Plot the surface
|
|
||||||
hold on
|
|
||||||
|
|
||||||
for idx = 2:length(z)
|
|
||||||
zlin = ones(size(X, 1))* z(idx); % Generate z data
|
|
||||||
mesh(x, y, zlin, 'EdgeColor','b') % Plot the surface
|
|
||||||
end
|
|
||||||
|
|
||||||
% set the axes labels' properties
|
|
||||||
xlabel(gca, {'$x / l_o ~ (m)$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
ylabel(gca, {'$y / l_o ~ (m)$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
zlabel(gca, {'$z / l_o ~ (m)$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
title(gca, 'Real Space', ...
|
|
||||||
'Interpreter', 'tex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
|
|
||||||
x = Transf.kx;
|
|
||||||
y = Transf.ky;
|
|
||||||
z = Transf.kz;
|
|
||||||
|
|
||||||
[X,Y] = meshgrid(x,y);
|
|
||||||
|
|
||||||
subplot(1,2,2)
|
|
||||||
zlin = ones(size(X, 1)) * z(1); % Generate z data
|
|
||||||
mesh(x, y, zlin, 'EdgeColor','b') % Plot the surface
|
|
||||||
hold on
|
|
||||||
|
|
||||||
for idx = 2:length(z)
|
|
||||||
zlin = ones(size(X, 1))* z(idx); % Generate z data
|
|
||||||
mesh(x, y, zlin, 'EdgeColor','b') % Plot the surface
|
|
||||||
end
|
|
||||||
|
|
||||||
% set the axes labels' properties
|
|
||||||
xlabel(gca, {'$k_x / l_o ~ (m^{-1})$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
ylabel(gca, {'$k_y / l_o ~ (m^{-1})$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
zlabel(gca, {'$k_z / l_o ~ (m^{-1})$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
title(gca, 'Fourier Space', ...
|
|
||||||
'Interpreter', 'tex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
end
|
|
@ -1,53 +0,0 @@
|
|||||||
function visualizeGSWavefunction(run_index)
|
|
||||||
set(0,'defaulttextInterpreter','latex')
|
|
||||||
set(groot, 'defaultAxesTickLabelInterpreter','latex'); set(groot, 'defaultLegendInterpreter','latex');
|
|
||||||
|
|
||||||
folder_path = './Data';
|
|
||||||
|
|
||||||
Data = load(sprintf(horzcat(folder_path, '/Run_%03i/psi_gs.mat'),run_index),'psi','Params','Transf','Observ');
|
|
||||||
|
|
||||||
psi = Data.psi;
|
|
||||||
Params = Data.Params;
|
|
||||||
Transf = Data.Transf;
|
|
||||||
Observ = Data.Observ;
|
|
||||||
|
|
||||||
format long
|
|
||||||
x = Transf.x*Params.l0*1e6;
|
|
||||||
y = Transf.y*Params.l0*1e6;
|
|
||||||
z = Transf.z*Params.l0*1e6;
|
|
||||||
dx = x(2)-x(1); dy = y(2)-y(1); dz = z(2)-z(1);
|
|
||||||
|
|
||||||
%Plotting
|
|
||||||
|
|
||||||
subplot(2,3,1)
|
|
||||||
n = abs(psi).^2;
|
|
||||||
nxz = squeeze(trapz(n*dy,2));
|
|
||||||
nyz = squeeze(trapz(n*dx,1));
|
|
||||||
nxy = squeeze(trapz(n*dz,3));
|
|
||||||
|
|
||||||
plotxz = pcolor(x,z,nxz');
|
|
||||||
set(plotxz, 'EdgeColor', 'none');
|
|
||||||
xlabel('$x$ [$\mu$m]'); ylabel('$z$ [$\mu$m]');
|
|
||||||
|
|
||||||
subplot(2,3,2)
|
|
||||||
plotyz = pcolor(y,z,nyz');
|
|
||||||
set(plotyz, 'EdgeColor', 'none');
|
|
||||||
xlabel('$y$ [$\mu$m]'); ylabel('$z$ [$\mu$m]');
|
|
||||||
|
|
||||||
subplot(2,3,3)
|
|
||||||
plotxy = pcolor(x,y,nxy');
|
|
||||||
set(plotxy, 'EdgeColor', 'none');
|
|
||||||
xlabel('$x$ [$\mu$m]'); ylabel('$y$ [$\mu$m]');
|
|
||||||
|
|
||||||
subplot(2,3,4)
|
|
||||||
plot(-log10(Observ.residual),'-b')
|
|
||||||
ylabel('$-\mathrm{log}_{10}(r)$'); xlabel('steps');
|
|
||||||
|
|
||||||
subplot(2,3,5)
|
|
||||||
plot(Observ.EVec,'-b')
|
|
||||||
ylabel('$E$'); xlabel('steps');
|
|
||||||
|
|
||||||
subplot(2,3,6)
|
|
||||||
plot(Observ.mucVec,'-b')
|
|
||||||
ylabel('$\mu$'); xlabel('steps');
|
|
||||||
end
|
|
@ -1,94 +0,0 @@
|
|||||||
function visualizeSpace(Transf)
|
|
||||||
|
|
||||||
x = Transf.x;
|
|
||||||
y = Transf.y;
|
|
||||||
z = Transf.z;
|
|
||||||
|
|
||||||
[X,Y] = meshgrid(x,y);
|
|
||||||
|
|
||||||
height = 20;
|
|
||||||
width = 45;
|
|
||||||
figure(1)
|
|
||||||
clf
|
|
||||||
set(gcf, 'Units', 'centimeters')
|
|
||||||
set(gcf, 'Position', [2 4 width height])
|
|
||||||
set(gcf, 'PaperPositionMode', 'auto')
|
|
||||||
|
|
||||||
subplot(1,2,1)
|
|
||||||
zlin = ones(size(X, 1)) * z(1); % Generate z data
|
|
||||||
mesh(x, y, zlin, 'EdgeColor','b') % Plot the surface
|
|
||||||
hold on
|
|
||||||
|
|
||||||
for idx = 2:length(z)
|
|
||||||
zlin = ones(size(X, 1))* z(idx); % Generate z data
|
|
||||||
mesh(x, y, zlin, 'EdgeColor','b') % Plot the surface
|
|
||||||
end
|
|
||||||
|
|
||||||
% set the axes labels' properties
|
|
||||||
xlabel(gca, {'$x / l_o ~ (m)$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
ylabel(gca, {'$y / l_o ~ (m)$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
zlabel(gca, {'$z / l_o ~ (m)$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
title(gca, 'Real Space', ...
|
|
||||||
'Interpreter', 'tex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
|
|
||||||
x = Transf.kx;
|
|
||||||
y = Transf.ky;
|
|
||||||
z = Transf.kz;
|
|
||||||
|
|
||||||
[X,Y] = meshgrid(x,y);
|
|
||||||
|
|
||||||
subplot(1,2,2)
|
|
||||||
zlin = ones(size(X, 1)) * z(1); % Generate z data
|
|
||||||
mesh(x, y, zlin, 'EdgeColor','b') % Plot the surface
|
|
||||||
hold on
|
|
||||||
|
|
||||||
for idx = 2:length(z)
|
|
||||||
zlin = ones(size(X, 1))* z(idx); % Generate z data
|
|
||||||
mesh(x, y, zlin, 'EdgeColor','b') % Plot the surface
|
|
||||||
end
|
|
||||||
|
|
||||||
% set the axes labels' properties
|
|
||||||
xlabel(gca, {'$k_x / l_o ~ (m^{-1})$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
ylabel(gca, {'$k_y / l_o ~ (m^{-1})$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
zlabel(gca, {'$k_z / l_o ~ (m^{-1})$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
title(gca, 'Fourier Space', ...
|
|
||||||
'Interpreter', 'tex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
end
|
|
@ -1,98 +0,0 @@
|
|||||||
function visualizeTrapPotential(V,Params,Transf)
|
|
||||||
set(0,'defaulttextInterpreter','latex')
|
|
||||||
set(groot, 'defaultAxesTickLabelInterpreter','latex'); set(groot, 'defaultLegendInterpreter','latex');
|
|
||||||
|
|
||||||
format long
|
|
||||||
x = Transf.x*Params.l0*1e6;
|
|
||||||
y = Transf.y*Params.l0*1e6;
|
|
||||||
z = Transf.z*Params.l0*1e6;
|
|
||||||
|
|
||||||
dx = x(2)-x(1); dy = y(2)-y(1); dz = z(2)-z(1);
|
|
||||||
|
|
||||||
%Plotting
|
|
||||||
height = 10;
|
|
||||||
width = 45;
|
|
||||||
figure(1)
|
|
||||||
clf
|
|
||||||
set(gcf, 'Units', 'centimeters')
|
|
||||||
set(gcf, 'Position', [2 8 width height])
|
|
||||||
set(gcf, 'PaperPositionMode', 'auto')
|
|
||||||
|
|
||||||
subplot(1,3,1)
|
|
||||||
n = V;
|
|
||||||
nxz = squeeze(trapz(n*dy,2));
|
|
||||||
nyz = squeeze(trapz(n*dx,1));
|
|
||||||
nxy = squeeze(trapz(n*dz,3));
|
|
||||||
|
|
||||||
nxz = nxz./max(nxz(:));
|
|
||||||
nyz = nyz./max(nyz(:));
|
|
||||||
nxy = nxy./max(nxy(:));
|
|
||||||
|
|
||||||
plotxz = pcolor(x,z,nxz');
|
|
||||||
set(plotxz, 'EdgeColor', 'none');
|
|
||||||
xlabel(gca, {'$x$ ($\mu$m)'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
ylabel(gca, {'$z$ ($\mu$m)'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
title(gca, {'$V_{xz}$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
colorbar
|
|
||||||
|
|
||||||
subplot(1,3,2)
|
|
||||||
plotyz = pcolor(y,z,nyz');
|
|
||||||
set(plotyz, 'EdgeColor', 'none');
|
|
||||||
xlabel(gca, {'$y$ ($\mu$m)'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
ylabel(gca, {'$z$ ($\mu$m)'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
title(gca, {'$V_{yz}$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
colorbar
|
|
||||||
|
|
||||||
subplot(1,3,3)
|
|
||||||
plotxy = pcolor(x,y,nxy');
|
|
||||||
set(plotxy, 'EdgeColor', 'none');
|
|
||||||
xlabel(gca, {'$x$ ($\mu$m)'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
ylabel(gca, {'$y$ ($\mu$m)'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
title(gca, {'$V_{xy}$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
colorbar
|
|
||||||
end
|
|
@ -1,92 +0,0 @@
|
|||||||
function visualizeWavefunction(psi,Params,Transf)
|
|
||||||
|
|
||||||
set(0,'defaulttextInterpreter','latex')
|
|
||||||
set(groot, 'defaultAxesTickLabelInterpreter','latex'); set(groot, 'defaultLegendInterpreter','latex');
|
|
||||||
|
|
||||||
format long
|
|
||||||
x = Transf.x*Params.l0*1e6;
|
|
||||||
y = Transf.y*Params.l0*1e6;
|
|
||||||
z = Transf.z*Params.l0*1e6;
|
|
||||||
|
|
||||||
dx = x(2)-x(1); dy = y(2)-y(1); dz = z(2)-z(1);
|
|
||||||
|
|
||||||
%Plotting
|
|
||||||
height = 10;
|
|
||||||
width = 45;
|
|
||||||
figure(1)
|
|
||||||
clf
|
|
||||||
set(gcf, 'Units', 'centimeters')
|
|
||||||
set(gcf, 'Position', [2 8 width height])
|
|
||||||
set(gcf, 'PaperPositionMode', 'auto')
|
|
||||||
|
|
||||||
subplot(1,3,1)
|
|
||||||
n = abs(psi).^2;
|
|
||||||
nxz = squeeze(trapz(n*dy,2));
|
|
||||||
nyz = squeeze(trapz(n*dx,1));
|
|
||||||
nxy = squeeze(trapz(n*dz,3));
|
|
||||||
|
|
||||||
plotxz = pcolor(x,z,nxz');
|
|
||||||
set(plotxz, 'EdgeColor', 'none');
|
|
||||||
xlabel(gca, {'$x$ ($\mu$m)'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
ylabel(gca, {'$z$ ($\mu$m)'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
title(gca, {'$|\Psi_{xz}|^2$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
|
|
||||||
subplot(1,3,2)
|
|
||||||
plotyz = pcolor(y,z,nyz');
|
|
||||||
set(plotyz, 'EdgeColor', 'none');
|
|
||||||
xlabel(gca, {'$y$ ($\mu$m)'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
ylabel(gca, {'$z$ ($\mu$m)'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
title(gca, {'$|\Psi_{yz}|^2$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
|
|
||||||
subplot(1,3,3)
|
|
||||||
plotxy = pcolor(x,y,nxy');
|
|
||||||
set(plotxy, 'EdgeColor', 'none');
|
|
||||||
xlabel(gca, {'$x$ ($\mu$m)'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
ylabel(gca, {'$y$ ($\mu$m)'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
title(gca, {'$|\Psi_{xy}|^2$'}, ...
|
|
||||||
'Interpreter', 'latex', ...
|
|
||||||
'FontName', 'Times New Roman', ...
|
|
||||||
'FontSize', 14, ...
|
|
||||||
'FontWeight', 'normal', ...
|
|
||||||
'FontAngle', 'normal')
|
|
||||||
end
|
|
@ -1,50 +0,0 @@
|
|||||||
set(0,'defaulttextInterpreter','latex')
|
|
||||||
set(groot, 'defaultAxesTickLabelInterpreter','latex'); set(groot, 'defaultLegendInterpreter','latex');
|
|
||||||
format long
|
|
||||||
|
|
||||||
runIdx = 6;
|
|
||||||
|
|
||||||
load(sprintf('./Data/Run_%03i/psi_gs.mat',runIdx),'psi','muchem','Observ','t_idx','Transf','Params','VDk','V');
|
|
||||||
|
|
||||||
x = Transf.x*Params.l0*1e6;
|
|
||||||
y = Transf.y*Params.l0*1e6;
|
|
||||||
z = Transf.z*Params.l0*1e6;
|
|
||||||
%percentcomplete = linspace(0,1,Params.cut_off/200);
|
|
||||||
|
|
||||||
dx = x(2)-x(1); dy = y(2)-y(1); dz = z(2)-z(1);
|
|
||||||
%Plotting
|
|
||||||
subplot(2,3,1)
|
|
||||||
n = abs(psi).^2;
|
|
||||||
nxz = squeeze(trapz(n*dy,2));
|
|
||||||
nyz = squeeze(trapz(n*dx,1));
|
|
||||||
nxy = squeeze(trapz(n*dz,3));
|
|
||||||
|
|
||||||
plotxz = pcolor(x,z,nxz');
|
|
||||||
set(plotxz, 'EdgeColor', 'none');
|
|
||||||
xlabel('$x$ [$\mu$m]'); ylabel('$z$ [$\mu$m]');
|
|
||||||
|
|
||||||
subplot(2,3,2)
|
|
||||||
plotyz = pcolor(y,z,nyz');
|
|
||||||
set(plotyz, 'EdgeColor', 'none');
|
|
||||||
xlabel('$y$ [$\mu$m]'); ylabel('$z$ [$\mu$m]');
|
|
||||||
|
|
||||||
subplot(2,3,3)
|
|
||||||
plotxy = pcolor(x,y,nxy');
|
|
||||||
set(plotxy, 'EdgeColor', 'none');
|
|
||||||
xlabel('$x$ [$\mu$m]'); ylabel('$y$ [$\mu$m]');
|
|
||||||
|
|
||||||
subplot(2,3,4)
|
|
||||||
plot(-log10(Observ.residual),'-b')
|
|
||||||
ylabel('$-\mathrm{log}_{10}(r)$'); xlabel('steps');
|
|
||||||
|
|
||||||
subplot(2,3,5)
|
|
||||||
plot(Observ.EVec,'-b')
|
|
||||||
ylabel('$E$'); xlabel('steps');
|
|
||||||
|
|
||||||
subplot(2,3,6)
|
|
||||||
plot(Observ.mucVec,'-b')
|
|
||||||
ylabel('$\mu$'); xlabel('steps');
|
|
||||||
% xlim([0,1]); ylim([0,8]);
|
|
||||||
% xlim([0,1]); ylim([0,8]);
|
|
||||||
|
|
||||||
Ecomp = energy_components(psi,Params,Transf,VDk,V);
|
|
@ -1,45 +0,0 @@
|
|||||||
%% This script is testing the functionalities of the Dipolar Gas Simulator
|
|
||||||
%
|
|
||||||
% Important: Run only sectionwise!!
|
|
||||||
|
|
||||||
%% - Create Simulator, Potential and Calculator object with specified options
|
|
||||||
|
|
||||||
OptionsStruct = struct;
|
|
||||||
|
|
||||||
OptionsStruct.NumberOfAtoms = 1E6;
|
|
||||||
OptionsStruct.DipolarPolarAngle = pi/2;
|
|
||||||
OptionsStruct.DipolarAzimuthAngle = 0;
|
|
||||||
OptionsStruct.ScatteringLength = 89;
|
|
||||||
|
|
||||||
OptionsStruct.TrapFrequencies = [50, 10, 150];
|
|
||||||
OptionsStruct.TrapDepth = 5;
|
|
||||||
OptionsStruct.BoxSize = 15;
|
|
||||||
OptionsStruct.TrapPotentialType = 'Harmonic';
|
|
||||||
|
|
||||||
OptionsStruct.NumberOfGridPoints = [64, 32, 64];
|
|
||||||
OptionsStruct.Dimensions = [20, 40, 80];
|
|
||||||
OptionsStruct.CutoffType = 'Cylindrical';
|
|
||||||
OptionsStruct.SimulationMode = 'ImaginaryTimeEvolution'; % 'ImaginaryTimeEvolution' | 'RealTimeEvolution'
|
|
||||||
OptionsStruct.TimeStepSize = 50E-6; % in s
|
|
||||||
OptionsStruct.NumberOfTimeSteps = 200; % in s
|
|
||||||
OptionsStruct.EnergyTolerance = 5E-10;
|
|
||||||
|
|
||||||
OptionsStruct.JobNumber = 1;
|
|
||||||
OptionsStruct.SaveData = true;
|
|
||||||
OptionsStruct.SaveDirectory = './Data';
|
|
||||||
options = Helper.convertstruct2cell(OptionsStruct);
|
|
||||||
clear OptionsStruct
|
|
||||||
|
|
||||||
sim = Simulator.DipolarGas(options{:});
|
|
||||||
pot = Simulator.Potentials(options{:});
|
|
||||||
sim.Potential = pot.trap(); % + pot.repulsive_chopstick();
|
|
||||||
|
|
||||||
%-% Run Simulation %-%
|
|
||||||
[Params, Transf, psi, V, VDk] = sim.run();
|
|
||||||
|
|
||||||
%% - Plot numerical grid
|
|
||||||
Plotter.visualizeSpace(Transf)
|
|
||||||
%% - Plot trap potential
|
|
||||||
Plotter.visualizeTrapPotential(V,Params,Transf)
|
|
||||||
%% - Plot initial wavefunction
|
|
||||||
Plotter.visualizeWavefunction(psi,Params,Transf)
|
|
@ -1,38 +0,0 @@
|
|||||||
%% This script is testing the functionalities of the Dipolar Gas Simulator
|
|
||||||
%
|
|
||||||
% Important: Run only sectionwise!!
|
|
||||||
|
|
||||||
%% - Create Simulator, Potential and Calculator object with specified options
|
|
||||||
|
|
||||||
OptionsStruct = struct;
|
|
||||||
|
|
||||||
OptionsStruct.NumberOfAtoms = 1.24E5;
|
|
||||||
OptionsStruct.DipolarPolarAngle = 0;
|
|
||||||
OptionsStruct.DipolarAzimuthAngle = 0;
|
|
||||||
OptionsStruct.ScatteringLength = 86;
|
|
||||||
|
|
||||||
OptionsStruct.TrapFrequencies = [44.97, 10.4, 126.3];
|
|
||||||
OptionsStruct.TrapDepth = 5;
|
|
||||||
OptionsStruct.BoxSize = 15;
|
|
||||||
OptionsStruct.TrapPotentialType = 'Harmonic';
|
|
||||||
|
|
||||||
OptionsStruct.NumberOfGridPoints = [128, 256, 128];
|
|
||||||
OptionsStruct.Dimensions = [50, 120, 150];
|
|
||||||
OptionsStruct.CutoffType = 'Cylindrical';
|
|
||||||
OptionsStruct.SimulationMode = 'ImaginaryTimeEvolution'; % 'ImaginaryTimeEvolution' | 'RealTimeEvolution'
|
|
||||||
OptionsStruct.TimeStepSize = 500E-6; % in s
|
|
||||||
OptionsStruct.NumberOfTimeSteps = 2E6; % in s
|
|
||||||
OptionsStruct.EnergyTolerance = 5E-10;
|
|
||||||
|
|
||||||
OptionsStruct.JobNumber = 1;
|
|
||||||
OptionsStruct.SaveData = true;
|
|
||||||
OptionsStruct.SaveDirectory = './Data';
|
|
||||||
options = Helper.convertstruct2cell(OptionsStruct);
|
|
||||||
clear OptionsStruct
|
|
||||||
|
|
||||||
sim = Simulator.DipolarGas(options{:});
|
|
||||||
pot = Simulator.Potentials(options{:});
|
|
||||||
sim.Potential = pot.trap(); % + pot.repulsive_chopstick();
|
|
||||||
|
|
||||||
%-% Run Simulation %-%
|
|
||||||
[Params, Transf, psi, V, VDk] = sim.run();
|
|
@ -1,97 +0,0 @@
|
|||||||
classdef Calculator < handle & matlab.mixin.Copyable
|
|
||||||
|
|
||||||
properties (Access = private)
|
|
||||||
|
|
||||||
CalculatorDefaults = struct('ChemicalPotential', 1, ...
|
|
||||||
'EnergyComponents', 1, ...
|
|
||||||
'NormalizedResiduals', 1, ...
|
|
||||||
'OrderParameter', 1, ...
|
|
||||||
'PhaseCoherence', 1, ...
|
|
||||||
'TotalEnergy', 1, ...
|
|
||||||
'CutoffType', 'Cylindrical');
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
properties (Access = public)
|
|
||||||
ChemicalPotential;
|
|
||||||
EnergyComponents;
|
|
||||||
NormalizedResiduals;
|
|
||||||
OrderParameter;
|
|
||||||
PhaseCoherence;
|
|
||||||
TotalEnergy;
|
|
||||||
CutoffType;
|
|
||||||
end
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
%- Methods
|
|
||||||
|
|
||||||
methods
|
|
||||||
function this = Calculator(varargin)
|
|
||||||
|
|
||||||
p = inputParser;
|
|
||||||
p.KeepUnmatched = true;
|
|
||||||
addParameter(p, 'CutoffType', this.CalculatorDefaults.CutoffType,...
|
|
||||||
@(x) any(strcmpi(x,{'Cylindrical','CylindricalInfiniteZ', 'Spherical'})));
|
|
||||||
|
|
||||||
p.parse(varargin{:});
|
|
||||||
|
|
||||||
this.ChemicalPotential = this.CalculatorDefaults.ChemicalPotential;
|
|
||||||
this.EnergyComponents = this.CalculatorDefaults.EnergyComponents;
|
|
||||||
this.NormalizedResiduals = this.CalculatorDefaults.NormalizedResiduals;
|
|
||||||
this.OrderParameter = this.CalculatorDefaults.OrderParameter;
|
|
||||||
this.PhaseCoherence = this.CalculatorDefaults.PhaseCoherence;
|
|
||||||
this.TotalEnergy = this.CalculatorDefaults.TotalEnergy;
|
|
||||||
this.CutoffType = p.Results.CutoffType;
|
|
||||||
end
|
|
||||||
|
|
||||||
function restoreDefaults(this)
|
|
||||||
this.ChemicalPotential = this.CalculatorDefaults.ChemicalPotential;
|
|
||||||
this.EnergyComponents = this.CalculatorDefaults.EnergyComponents;
|
|
||||||
this.NormalizedResiduals = this.CalculatorDefaults.NormalizedResiduals;
|
|
||||||
this.OrderParameter = this.CalculatorDefaults.OrderParameter;
|
|
||||||
this.PhaseCoherence = this.CalculatorDefaults.PhaseCoherence;
|
|
||||||
this.TotalEnergy = this.CalculatorDefaults.TotalEnergy;
|
|
||||||
this.CutoffType = this.CalculatorDefaults.CutoffType;
|
|
||||||
end
|
|
||||||
|
|
||||||
end %
|
|
||||||
|
|
||||||
% methods
|
|
||||||
|
|
||||||
% end % - setters and getters
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
%- Methods
|
|
||||||
|
|
||||||
methods(Access = protected)
|
|
||||||
function cp = copyElement(this)
|
|
||||||
% Shallow copy object
|
|
||||||
cp = copyElement@matlab.mixin.Copyable(this);
|
|
||||||
|
|
||||||
% Forces the setter to redefine the function handles to the new copied object
|
|
||||||
|
|
||||||
pl = properties(this);
|
|
||||||
for k = 1:length(pl)
|
|
||||||
sc = superclasses(this.(pl{k}));
|
|
||||||
if any(contains(sc,{'matlab.mixin.Copyable'}))
|
|
||||||
cp.(pl{k}) = this.(pl{k}).copy();
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
methods (Static)
|
|
||||||
|
|
||||||
% Creates an Instance of Class, ensures singleton behaviour (that there
|
|
||||||
% can only be one Instance of this class
|
|
||||||
function singleObj = getInstance(varargin)
|
|
||||||
% Creates an Instance of Class, ensures singleton behaviour
|
|
||||||
persistent localObj;
|
|
||||||
if isempty(localObj) || ~isvalid(localObj)
|
|
||||||
localObj = Simulator.Calculator(varargin{:});
|
|
||||||
end
|
|
||||||
singleObj = localObj;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,29 +0,0 @@
|
|||||||
function muchem = calculateChemicalPotential(~,psi,Params,Transf,VDk,V)
|
|
||||||
|
|
||||||
%Parameters
|
|
||||||
normfac = Params.Lx*Params.Ly*Params.Lz/numel(psi);
|
|
||||||
KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2);
|
|
||||||
|
|
||||||
% DDIs
|
|
||||||
frho=fftn(abs(psi).^2);
|
|
||||||
Phi=real(ifftn(frho.*VDk));
|
|
||||||
|
|
||||||
Eddi = (Params.gdd*Phi.*abs(psi).^2);
|
|
||||||
|
|
||||||
%Kinetic energy
|
|
||||||
Ekin = KEop.*abs(fftn(psi)*normfac).^2;
|
|
||||||
Ekin = trapz(Ekin(:))*Transf.dkx*Transf.dky*Transf.dkz/(2*pi)^3;
|
|
||||||
|
|
||||||
%Potential energy
|
|
||||||
Epot = V.*abs(psi).^2;
|
|
||||||
|
|
||||||
%Contact interactions
|
|
||||||
Eint = Params.gs*abs(psi).^4;
|
|
||||||
|
|
||||||
%Quantum fluctuations
|
|
||||||
Eqf = Params.gammaQF*abs(psi).^5;
|
|
||||||
|
|
||||||
%Total energy
|
|
||||||
muchem = Ekin + trapz(Epot(:) + Eint(:) + Eddi(:) + Eqf(:))*Transf.dx*Transf.dy*Transf.dz; %
|
|
||||||
muchem = muchem / Params.N;
|
|
||||||
end
|
|
@ -1,35 +0,0 @@
|
|||||||
function E = calculateEnergyComponents(~,psi,Params,Transf,VDk,V)
|
|
||||||
|
|
||||||
%Parameters
|
|
||||||
|
|
||||||
KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2);
|
|
||||||
normfac = Params.Lx*Params.Ly*Params.Lz/numel(psi);
|
|
||||||
|
|
||||||
% DDIs
|
|
||||||
frho = fftn(abs(psi).^2);
|
|
||||||
Phi = real(ifftn(frho.*VDk));
|
|
||||||
|
|
||||||
Eddi = 0.5*Params.gdd*Phi.*abs(psi).^2;
|
|
||||||
E.Eddi = trapz(Eddi(:))*Transf.dx*Transf.dy*Transf.dz;
|
|
||||||
|
|
||||||
% EddiTot = trapz(Eddi(:))*Transf.dx*Transf.dy*Transf.dz;
|
|
||||||
|
|
||||||
%Kinetic energy
|
|
||||||
% psik = ifftshift(fftn(fftshift(psi)))*normfac;
|
|
||||||
|
|
||||||
Ekin = KEop.*abs(fftn(psi)*normfac).^2;
|
|
||||||
E.Ekin = trapz(Ekin(:))*Transf.dkx*Transf.dky*Transf.dkz/(2*pi)^3;
|
|
||||||
|
|
||||||
% Potential energy
|
|
||||||
Epot = V.*abs(psi).^2;
|
|
||||||
E.Epot = trapz(Epot(:))*Transf.dx*Transf.dy*Transf.dz;
|
|
||||||
|
|
||||||
%Contact interactions
|
|
||||||
Eint = 0.5*Params.gs*abs(psi).^4;
|
|
||||||
E.Eint = trapz(Eint(:))*Transf.dx*Transf.dy*Transf.dz;
|
|
||||||
|
|
||||||
%Quantum fluctuations
|
|
||||||
Eqf = 0.4*Params.gammaQF*abs(psi).^5;
|
|
||||||
E.Eqf = trapz(Eqf(:))*Transf.dx*Transf.dy*Transf.dz;
|
|
||||||
|
|
||||||
end
|
|
@ -1,25 +0,0 @@
|
|||||||
function res = calculateNormalizedResiduals(~,psi,Params,Transf,VDk,V,muchem)
|
|
||||||
|
|
||||||
KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2);
|
|
||||||
|
|
||||||
% DDIs
|
|
||||||
frho=fftn(abs(psi).^2);
|
|
||||||
Phi=real(ifftn(frho.*VDk));
|
|
||||||
|
|
||||||
Eddi = Params.gdd*Phi.*psi;
|
|
||||||
|
|
||||||
%Kinetic energy
|
|
||||||
Ekin = ifftn(KEop.*fftn(psi));
|
|
||||||
|
|
||||||
%Potential energy
|
|
||||||
Epot = V.*psi;
|
|
||||||
|
|
||||||
%Contact interactions
|
|
||||||
Eint = Params.gs*abs(psi).^2.*psi;
|
|
||||||
|
|
||||||
%Quantum fluctuations
|
|
||||||
Eqf = Params.gammaQF*abs(psi).^3.*psi;
|
|
||||||
|
|
||||||
%Total energy
|
|
||||||
res = trapz(abs(Ekin(:) + Epot(:) + Eint(:) + Eddi(:) + Eqf(:) - muchem*psi(:))*Transf.dx*Transf.dy*Transf.dz)/trapz(abs(muchem*psi(:))*Transf.dx*Transf.dy*Transf.dz);
|
|
||||||
end
|
|
@ -1,39 +0,0 @@
|
|||||||
function VDkSemi = calculateNumericalHankelTransform(~,kr,kz,Rmax,Zmax,Nr)
|
|
||||||
|
|
||||||
% accuracy inputs for numerical integration
|
|
||||||
if(nargin==5)
|
|
||||||
Nr = 5e4;
|
|
||||||
end
|
|
||||||
|
|
||||||
Nz = 64;
|
|
||||||
farRmultiple = 2000;
|
|
||||||
|
|
||||||
% midpoint grids for the integration over 0<z<Zmax, Rmax<r<farRmultiple*Rmax (i.e. starts at Rmax)
|
|
||||||
dr=(farRmultiple-1)*Rmax/Nr;
|
|
||||||
r = ((1:Nr)'-0.5)*dr+Rmax;
|
|
||||||
dz=Zmax/Nz;
|
|
||||||
z = ((1:Nz)-0.5)*dz;
|
|
||||||
[R, Z] = ndgrid(r,z);
|
|
||||||
Rsq = R.^2 + Z.^2;
|
|
||||||
|
|
||||||
% real space interaction to be transformed
|
|
||||||
igrandbase = (1 - 3*Z.^2./Rsq)./Rsq.^(3/2);
|
|
||||||
|
|
||||||
% do the Hankel/Fourier-Bessel transform numerically
|
|
||||||
% prestore to ensure each besselj is only calculated once
|
|
||||||
% cell is faster than (:,:,krn) slicing
|
|
||||||
Nkr = numel(kr);
|
|
||||||
besselr = cell(Nkr,1);
|
|
||||||
for krn = 1:Nkr
|
|
||||||
besselr{krn} = repmat(r.*besselj(0,kr(krn)*r),1,Nz);
|
|
||||||
end
|
|
||||||
|
|
||||||
VDkSemi = zeros([Nkr,numel(kz)]);
|
|
||||||
for kzn = 1:numel(kz)
|
|
||||||
igrandbasez = repmat(cos(kz(kzn)*z),Nr,1) .* igrandbase;
|
|
||||||
for krn = 1:Nkr
|
|
||||||
igrand = igrandbasez.*besselr{krn};
|
|
||||||
VDkSemi(krn,kzn) = VDkSemi(krn,kzn) - sum(igrand(:))*dz*dr;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,58 +0,0 @@
|
|||||||
function [m_Order] = calculateOrderParameter(~,psi,Transf,Params,VDk,V,T,muchem)
|
|
||||||
|
|
||||||
NumRealiz = 100;
|
|
||||||
|
|
||||||
Mx = numel(Transf.x);
|
|
||||||
My = numel(Transf.y);
|
|
||||||
Mz = numel(Transf.z);
|
|
||||||
|
|
||||||
r = normrnd(0,1,size(psi));
|
|
||||||
theta = rand(size(psi));
|
|
||||||
noise = r.*exp(2*pi*1i*theta);
|
|
||||||
|
|
||||||
KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2);
|
|
||||||
Gamma = 1-1i*Params.gamma_S;
|
|
||||||
dt = Params.dt;
|
|
||||||
|
|
||||||
avgpsi = 0;
|
|
||||||
avgpsi2 = 0;
|
|
||||||
|
|
||||||
for jj = 1:NumRealiz
|
|
||||||
%generate initial state
|
|
||||||
xi = sqrt(2*Params.gamma_S*Params.kbol*T*10^(-9)*dt/(Params.hbar*Params.w0*Transf.dx*Transf.dy*Transf.dz));
|
|
||||||
swapx = randi(length(Transf.x),1,length(Transf.x));
|
|
||||||
swapy = randi(length(Transf.y),1,length(Transf.y));
|
|
||||||
swapz = randi(length(Transf.z),1,length(Transf.z));
|
|
||||||
psi_j = psi + xi * noise(swapx,swapy,swapz);
|
|
||||||
|
|
||||||
% --- % propagate forward in time 1 time step:
|
|
||||||
%kin
|
|
||||||
psi_j = fftn(psi_j);
|
|
||||||
psi_j = psi_j.*exp(-0.5*1i*Gamma*dt*KEop);
|
|
||||||
psi_j = ifftn(psi_j);
|
|
||||||
|
|
||||||
%DDI
|
|
||||||
frho = fftn(abs(psi_j).^2);
|
|
||||||
Phi = real(ifftn(frho.*VDk));
|
|
||||||
|
|
||||||
%Real-space
|
|
||||||
psi_j = psi_j.*exp(-1i*Gamma*dt*(V + Params.gs*abs(psi_j).^2 + Params.gammaQF*abs(psi_j).^3 + Params.gdd*Phi - muchem));
|
|
||||||
|
|
||||||
%kin
|
|
||||||
psi_j = fftn(psi_j);
|
|
||||||
psi_j = psi_j.*exp(-0.5*1i*Gamma*dt*KEop);
|
|
||||||
psi_j = ifftn(psi_j);
|
|
||||||
|
|
||||||
%Projection
|
|
||||||
kcut = sqrt(2*Params.e_cut);
|
|
||||||
K = (Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2)<kcut.^2;
|
|
||||||
psi_j = ifftn(K.*fftn(psi_j));
|
|
||||||
|
|
||||||
% --- %
|
|
||||||
avgpsi = avgpsi + abs(sum(psi_j(:)))/NumRealiz;
|
|
||||||
avgpsi2 = avgpsi2 + sum(abs(psi_j(:)).^2)/NumRealiz;
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
m_Order = 1/sqrt(Mx*My*Mz)*avgpsi/sqrt(avgpsi2);
|
|
||||||
end
|
|
@ -1,19 +0,0 @@
|
|||||||
function [PhaseC] = calculatePhaseCoherence(~,psi,Transf,Params)
|
|
||||||
|
|
||||||
norm = sum(sum(sum(abs(psi).^2,1),2),3)*Transf.dx*Transf.dy*Transf.dz;
|
|
||||||
psi = psi/sqrt(norm);
|
|
||||||
|
|
||||||
NumGlobalShifts = 800;
|
|
||||||
betas = []; phishift = [];
|
|
||||||
for jj = 1:NumGlobalShifts
|
|
||||||
phishift(jj) = -pi + 2*pi*(jj-1)/NumGlobalShifts;
|
|
||||||
betas(jj) = sum(sum(sum(abs(angle(psi*exp(-1i*phishift(jj)))).*abs(psi).^2)));
|
|
||||||
end
|
|
||||||
[minbeta,minidx] = min(betas);
|
|
||||||
|
|
||||||
psi = psi*exp(-1i*phishift(minidx));
|
|
||||||
phi = angle(psi);
|
|
||||||
|
|
||||||
avgphi = sum(sum(sum(phi.*abs(psi).^2,1),2),3)*Transf.dx*Transf.dy*Transf.dz;
|
|
||||||
PhaseC = sum(sum(sum(abs(angle(psi)-avgphi).*abs(psi).^2)))*Transf.dx*Transf.dy*Transf.dz;
|
|
||||||
end
|
|
@ -1,32 +0,0 @@
|
|||||||
function E = calculateTotalEnergy(~,psi,Params,Transf,VDk,V)
|
|
||||||
|
|
||||||
%Parameters
|
|
||||||
|
|
||||||
KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2);
|
|
||||||
normfac = Params.Lx*Params.Ly*Params.Lz/numel(psi);
|
|
||||||
|
|
||||||
% DDIs
|
|
||||||
frho = fftn(abs(psi).^2);
|
|
||||||
Phi = real(ifftn(frho.*VDk));
|
|
||||||
|
|
||||||
Eddi = 0.5*Params.gdd*Phi.*abs(psi).^2;
|
|
||||||
|
|
||||||
% EddiTot = trapz(Eddi(:))*Transf.dx*Transf.dy*Transf.dz;
|
|
||||||
|
|
||||||
%Kinetic energy
|
|
||||||
% psik = ifftshift(fftn(fftshift(psi)))*normfac;
|
|
||||||
|
|
||||||
Ekin = KEop.*abs(fftn(psi)*normfac).^2;
|
|
||||||
Ekin = trapz(Ekin(:))*Transf.dkx*Transf.dky*Transf.dkz/(2*pi)^3;
|
|
||||||
|
|
||||||
% Potential energy
|
|
||||||
Epot = V.*abs(psi).^2;
|
|
||||||
|
|
||||||
%Contact interactions
|
|
||||||
Eint = 0.5*Params.gs*abs(psi).^4;
|
|
||||||
|
|
||||||
%Quantum fluctuations
|
|
||||||
Eqf = 0.4*Params.gammaQF*abs(psi).^5;
|
|
||||||
|
|
||||||
E = Ekin + trapz(Epot(:) + Eint(:) + Eddi(:) + Eqf(:))*Transf.dx*Transf.dy*Transf.dz;
|
|
||||||
end
|
|
@ -1,64 +0,0 @@
|
|||||||
function VDk = calculateVDCutoff(this,Params,Transf,TransfRad)
|
|
||||||
% makes the dipolar interaction matrix, size numel(Params.kr) * numel(Params.kz)
|
|
||||||
% Rmax and Zmax are the interaction cutoffs
|
|
||||||
% VDk needs to be multiplied by Cdd
|
|
||||||
% approach is that of Lu, PRA 82, 023622 (2010)
|
|
||||||
|
|
||||||
% == Calulating the DDI potential in Fourier space with appropriate cutoff == %
|
|
||||||
% Cylindrical (semianalytic)
|
|
||||||
% Cylindrical infinite Z, polarized along x (analytic)
|
|
||||||
% Spherical
|
|
||||||
|
|
||||||
switch this.CutoffType
|
|
||||||
case 'Cylindrical' %Cylindrical (semianalytic)
|
|
||||||
Zcutoff = Params.Lz/2;
|
|
||||||
alph = acos((Transf.KX*sin(Params.theta)*cos(Params.phi)+Transf.KY*sin(Params.theta)*sin(Params.phi)+Transf.KZ*cos(Params.theta))./sqrt(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2));
|
|
||||||
alph(1) = pi/2;
|
|
||||||
|
|
||||||
% Analytic part of cutoff for slice 0<z<Zmax, 0<r<Inf Ronen, PRL 98, 030406 (2007)
|
|
||||||
cossq = cos(alph).^2;
|
|
||||||
VDk = cossq-1/3;
|
|
||||||
sinsq = 1 - cossq;
|
|
||||||
VDk = VDk + exp(-Zcutoff*sqrt(Transf.KX.^2+Transf.KY.^2)).*( sinsq .* cos(Zcutoff * Transf.KZ) - sqrt(sinsq.*cossq).*sin(Zcutoff * Transf.KZ) );
|
|
||||||
|
|
||||||
% Nonanalytic part
|
|
||||||
% For a cylindrical cutoff, we need to construct a kr grid based on the 3D parameters using Bessel quadrature
|
|
||||||
VDkNon = this.calculateNumericalHankelTransform(TransfRad.kr, TransfRad.kz, TransfRad.Rmax, Zcutoff);
|
|
||||||
|
|
||||||
% Interpolating the nonanalytic part onto 3D grid
|
|
||||||
fullkr = [-flip(TransfRad.kr)',TransfRad.kr'];
|
|
||||||
[KR,KZ] = ndgrid(fullkr,TransfRad.kz);
|
|
||||||
[KX3D,KY3D,KZ3D] = ndgrid(ifftshift(Transf.kx),ifftshift(Transf.ky),ifftshift(Transf.kz));
|
|
||||||
KR3D = sqrt(KX3D.^2 + KY3D.^2);
|
|
||||||
fullVDK = [flip(VDkNon',2),VDkNon']';
|
|
||||||
VDkNon = interpn(KR,KZ,fullVDK,KR3D,KZ3D,'spline',0); %Last argument is -1/3 for full VDk. 0 for nonanalytic piece?
|
|
||||||
VDkNon = fftshift(VDkNon);
|
|
||||||
|
|
||||||
VDk = VDk + VDkNon;
|
|
||||||
|
|
||||||
case 'CylindricalInfiniteZ' %Cylindrical infinite Z, polarized along x -- PRA 107, 033301 (2023)
|
|
||||||
alph = acos((Transf.KX*sin(Params.theta)*cos(Params.phi)+Transf.KY*sin(Params.theta)*sin(Params.phi)+Transf.KZ*cos(Params.theta))./sqrt(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2));
|
|
||||||
alph(1) = pi/2;
|
|
||||||
rhoc = max([abs(Transf.x),abs(Transf.y)]);
|
|
||||||
KR = sqrt(Transf.KX.^2+Transf.KY.^2);
|
|
||||||
func = @(n,u,v) v.^2./(u.^2+v.^2).*(v.*besselj(n,u).*besselk(n+1,v) - u.*besselj(n+1,u).*besselk(n,v));
|
|
||||||
VDk = -0.5*func(0,KR*rhoc,abs(Transf.KZ)*rhoc) + (Transf.KX.^2./KR.^2 - 0.5).*func(2,KR*rhoc,abs(Transf.KZ)*rhoc);
|
|
||||||
VDk = (1/3)*(3*(cos(alph).^2)-1) - VDk;
|
|
||||||
|
|
||||||
VDk(KR==0) = -1/3 + 1/2*abs(Transf.KZ(KR==0))*rhoc.*besselk(1,abs(Transf.KZ(KR==0))*rhoc);
|
|
||||||
VDk(Transf.KZ==0) = 1/6 + (Transf.KX(Transf.KZ==0).^2-Transf.KY(Transf.KZ==0).^2)./(KR(Transf.KZ==0).^2).*(1/2 - besselj(1,KR(Transf.KZ==0)*rhoc)./(KR(Transf.KZ==0)*rhoc));
|
|
||||||
VDk(1,1,1) = 1/6;
|
|
||||||
|
|
||||||
case 'Spherical' %Spherical
|
|
||||||
Rcut = min(Params.Lx/2,Params.Ly/2,Params.Lz/2);
|
|
||||||
alph = acos((Transf.KX*sin(Params.theta)*cos(Params.phi)+Transf.KY*sin(Params.theta)*sin(Params.phi)+Transf.KZ*cos(Params.theta))./sqrt(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2));
|
|
||||||
alph(1) = pi/2;
|
|
||||||
|
|
||||||
K = sqrt(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2);
|
|
||||||
VDk = (cos(alph).^2-1/3).*(1 + 3*cos(Rcut*K)./(Rcut^2.*K.^2) - 3*sin(Rcut*K)./(Rcut^3.*K.^3));
|
|
||||||
|
|
||||||
otherwise
|
|
||||||
disp('Choose a valid DDI cutoff type!')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,178 +0,0 @@
|
|||||||
classdef DipolarGas < handle & matlab.mixin.Copyable
|
|
||||||
|
|
||||||
properties (Access = public)
|
|
||||||
NumberOfAtoms;
|
|
||||||
DipolarPolarAngle;
|
|
||||||
DipolarAzimuthAngle
|
|
||||||
ScatteringLength;
|
|
||||||
TrapFrequencies;
|
|
||||||
NumberOfGridPoints;
|
|
||||||
Dimensions;
|
|
||||||
Potential;
|
|
||||||
|
|
||||||
SimulationMode;
|
|
||||||
TimeStepSize;
|
|
||||||
NumberOfTimeSteps;
|
|
||||||
EnergyTolerance;
|
|
||||||
MinimumTimeStepSize;
|
|
||||||
|
|
||||||
Calculator;
|
|
||||||
|
|
||||||
SimulationParameters;
|
|
||||||
|
|
||||||
%Flags
|
|
||||||
|
|
||||||
JobNumber;
|
|
||||||
DebugMode;
|
|
||||||
DoSave;
|
|
||||||
SaveDirectory;
|
|
||||||
end
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
%- Methods
|
|
||||||
|
|
||||||
methods
|
|
||||||
function this = DipolarGas(varargin)
|
|
||||||
|
|
||||||
p = inputParser;
|
|
||||||
p.KeepUnmatched = true;
|
|
||||||
addParameter(p, 'NumberOfAtoms', 1E6,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
|
|
||||||
addParameter(p, 'DipolarPolarAngle', pi/2,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x) && (x > -2*pi) && (x < 2*pi)));
|
|
||||||
addParameter(p, 'DipolarAzimuthAngle', pi/2,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x) && (x > -2*pi) && (x < 2*pi)));
|
|
||||||
addParameter(p, 'ScatteringLength', 120,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x) && (x > -150) && (x < 150)));
|
|
||||||
addParameter(p, 'TrapFrequencies', 100 * ones(1,3),...
|
|
||||||
@(x) assert(isnumeric(x) && isvector(x) && all(x > 0)));
|
|
||||||
addParameter(p, 'NumberOfGridPoints', 128 * ones(1,3),...
|
|
||||||
@(x) assert(isnumeric(x) && isvector(x) && all(x > 0)));
|
|
||||||
addParameter(p, 'Dimensions', 10 * ones(1,3),...
|
|
||||||
@(x) assert(isnumeric(x) && isvector(x) && all(x > 0)));
|
|
||||||
addParameter(p, 'SimulationMode', 'ImaginaryTimeEvolution',...
|
|
||||||
@(x) assert(any(strcmpi(x,{'ImaginaryTimeEvolution','RealTimeEvolution'}))));
|
|
||||||
addParameter(p, 'CutoffType', 'Cylindrical',...
|
|
||||||
@(x) assert(any(strcmpi(x,{'Cylindrical','CylindricalInfiniteZ', 'Spherical'}))));
|
|
||||||
addParameter(p, 'TimeStepSize', 5E-4,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
|
|
||||||
addParameter(p, 'NumberOfTimeSteps', 2e6,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
|
|
||||||
addParameter(p, 'EnergyTolerance', 1e-10,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
|
|
||||||
addParameter(p, 'MinimumTimeStepSize', 1e-6,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
|
|
||||||
addParameter(p, 'JobNumber', 1,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
|
|
||||||
addParameter(p, 'DebugMode', false,...
|
|
||||||
@islogical);
|
|
||||||
addParameter(p, 'SaveData', false,...
|
|
||||||
@islogical);
|
|
||||||
addParameter(p, 'SaveDirectory', './Data',...
|
|
||||||
@ischar);
|
|
||||||
|
|
||||||
p.parse(varargin{:});
|
|
||||||
|
|
||||||
this.NumberOfAtoms = p.Results.NumberOfAtoms;
|
|
||||||
this.DipolarPolarAngle = p.Results.DipolarPolarAngle;
|
|
||||||
this.DipolarAzimuthAngle = p.Results.DipolarAzimuthAngle;
|
|
||||||
this.ScatteringLength = p.Results.ScatteringLength;
|
|
||||||
this.TrapFrequencies = p.Results.TrapFrequencies;
|
|
||||||
this.NumberOfGridPoints = p.Results.NumberOfGridPoints;
|
|
||||||
this.Dimensions = p.Results.Dimensions;
|
|
||||||
this.Potential = NaN;
|
|
||||||
this.SimulationMode = p.Results.SimulationMode;
|
|
||||||
this.TimeStepSize = p.Results.TimeStepSize;
|
|
||||||
this.NumberOfTimeSteps = p.Results.NumberOfTimeSteps;
|
|
||||||
this.EnergyTolerance = p.Results.EnergyTolerance;
|
|
||||||
this.MinimumTimeStepSize = p.Results.MinimumTimeStepSize;
|
|
||||||
|
|
||||||
this.JobNumber = p.Results.JobNumber;
|
|
||||||
this.DebugMode = p.Results.DebugMode;
|
|
||||||
this.DoSave = p.Results.SaveData;
|
|
||||||
this.SaveDirectory = p.Results.SaveDirectory;
|
|
||||||
|
|
||||||
this.Calculator = Simulator.Calculator('CutoffType', p.Results.CutoffType);
|
|
||||||
|
|
||||||
this.SimulationParameters = this.setupParameters();
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
methods
|
|
||||||
function set.TimeStepSize(this, val)
|
|
||||||
assert(val > 1e-06, 'Not time efficient to compute for time steps smaller than 1 microsecond!');
|
|
||||||
this.TimeStepSize = val;
|
|
||||||
end
|
|
||||||
function ret = get.TimeStepSize(this)
|
|
||||||
ret = this.TimeStepSize;
|
|
||||||
end
|
|
||||||
function set.NumberOfTimeSteps(this, val)
|
|
||||||
assert(val <= 2E6, 'Not time efficient to compute for time spans longer than 2E6 seconds!');
|
|
||||||
this.NumberOfTimeSteps = val;
|
|
||||||
end
|
|
||||||
function ret = get.NumberOfTimeSteps(this)
|
|
||||||
ret = this.NumberOfTimeSteps;
|
|
||||||
end
|
|
||||||
function set.NumberOfAtoms(this, val)
|
|
||||||
assert(val <= 1E6, '!!Not time efficient to compute for atom numbers larger than 1,000,000!!');
|
|
||||||
this.NumberOfAtoms = val;
|
|
||||||
end
|
|
||||||
function ret = get.NumberOfAtoms(this)
|
|
||||||
ret = this.NumberOfAtoms;
|
|
||||||
end
|
|
||||||
function set.DebugMode(this, val)
|
|
||||||
this.DebugMode = val;
|
|
||||||
end
|
|
||||||
function ret = get.DebugMode(this)
|
|
||||||
ret = this.DebugMode;
|
|
||||||
end
|
|
||||||
function set.DoSave(this, val)
|
|
||||||
this.DoSave = val;
|
|
||||||
end
|
|
||||||
function ret = get.DoSave(this)
|
|
||||||
ret = this.DoSave;
|
|
||||||
end
|
|
||||||
function set.SaveDirectory(this, val)
|
|
||||||
this.SaveDirectory = val;
|
|
||||||
end
|
|
||||||
function ret = get.SaveDirectory(this)
|
|
||||||
ret = this.SaveDirectory;
|
|
||||||
end
|
|
||||||
end % - setters and getters
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
%- Methods
|
|
||||||
|
|
||||||
methods(Access = protected)
|
|
||||||
function cp = copyElement(this)
|
|
||||||
% Shallow copy object
|
|
||||||
cp = copyElement@matlab.mixin.Copyable(this);
|
|
||||||
|
|
||||||
% Forces the setter to redefine the function handles to the new copied object
|
|
||||||
|
|
||||||
pl = properties(this);
|
|
||||||
for k = 1:length(pl)
|
|
||||||
sc = superclasses(this.(pl{k}));
|
|
||||||
if any(contains(sc,{'matlab.mixin.Copyable'}))
|
|
||||||
cp.(pl{k}) = this.(pl{k}).copy();
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
methods (Static)
|
|
||||||
|
|
||||||
% Creates an Instance of Class, ensures singleton behaviour (that there
|
|
||||||
% can only be one Instance of this class
|
|
||||||
function singleObj = getInstance(varargin)
|
|
||||||
% Creates an Instance of Class, ensures singleton behaviour
|
|
||||||
persistent localObj;
|
|
||||||
if isempty(localObj) || ~isvalid(localObj)
|
|
||||||
localObj = Simulator.DipolarGas(varargin{:});
|
|
||||||
end
|
|
||||||
singleObj = localObj;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,19 +0,0 @@
|
|||||||
function [psi,V,VDk] = initialize(this,Params,Transf,TransfRad)
|
|
||||||
|
|
||||||
% == User-defined potential == %
|
|
||||||
V = this.Potential;
|
|
||||||
assert(~anynan(V), 'Potential not defined! Specify as <SimulatorObject>.Potential = <PotentialsObject>.trap() + <AdditionalTerms>.');
|
|
||||||
|
|
||||||
% == Calculating the DDIs == %
|
|
||||||
if isfile(strcat(this.SaveDirectory, '/VDk_M.mat'))
|
|
||||||
VDk = load(sprintf(strcat(this.SaveDirectory, '/VDk_M.mat')));
|
|
||||||
VDk = VDk.VDk;
|
|
||||||
else
|
|
||||||
VDk = this.Calculator.calculateVDCutoff(Params,Transf,TransfRad);
|
|
||||||
save(sprintf(strcat(this.SaveDirectory, '/VDk_M.mat')),'VDk');
|
|
||||||
end
|
|
||||||
fprintf('Computed and saved DDI potential in Fourier space with %s cutoff.\n', this.Calculator.CutoffType)
|
|
||||||
|
|
||||||
% == Setting up the initial wavefunction == %
|
|
||||||
psi = this.setupWavefunction(Params,Transf);
|
|
||||||
end
|
|
@ -1,187 +0,0 @@
|
|||||||
function [psi] = propagateWavefunction(this,psi,Params,Transf,VDk,V,t_idx,Observ)
|
|
||||||
set(0,'defaulttextInterpreter','latex')
|
|
||||||
set(groot, 'defaultAxesTickLabelInterpreter','latex'); set(groot, 'defaultLegendInterpreter','latex');
|
|
||||||
|
|
||||||
switch this.SimulationMode
|
|
||||||
case 'ImaginaryTimeEvolution'
|
|
||||||
dt=-1j*abs(this.TimeStepSize);
|
|
||||||
|
|
||||||
KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2);
|
|
||||||
Observ.residual = 1; Observ.res = 1;
|
|
||||||
|
|
||||||
muchem = this.Calculator.calculateChemicalPotential(psi,Params,Transf,VDk,V);
|
|
||||||
AdaptIdx = 0;
|
|
||||||
|
|
||||||
pb = Helper.ProgressBar();
|
|
||||||
pb.run('Running simulation in imaginary time: ');
|
|
||||||
|
|
||||||
while t_idx < Params.sim_time_cut_off
|
|
||||||
|
|
||||||
%kin
|
|
||||||
psi = fftn(psi);
|
|
||||||
psi = psi.*exp(-0.5*1i*dt*KEop);
|
|
||||||
psi = ifftn(psi);
|
|
||||||
|
|
||||||
%DDI
|
|
||||||
frho = fftn(abs(psi).^2);
|
|
||||||
Phi = real(ifftn(frho.*VDk));
|
|
||||||
|
|
||||||
%Real-space
|
|
||||||
psi = psi.*exp(-1i*dt*(V + Params.gs*abs(psi).^2 + Params.gdd*Phi + Params.gammaQF*abs(psi).^3 - muchem));
|
|
||||||
|
|
||||||
%kin
|
|
||||||
psi = fftn(psi);
|
|
||||||
psi = psi.*exp(-0.5*1i*dt*KEop);
|
|
||||||
psi = ifftn(psi);
|
|
||||||
|
|
||||||
%Renorm
|
|
||||||
Norm = trapz(abs(psi(:)).^2)*Transf.dx*Transf.dy*Transf.dz;
|
|
||||||
psi = sqrt(Params.N)*psi/sqrt(Norm);
|
|
||||||
|
|
||||||
muchem = this.Calculator.calculateChemicalPotential(psi,Params,Transf,VDk,V);
|
|
||||||
|
|
||||||
if mod(t_idx,1000) == 0
|
|
||||||
|
|
||||||
%Change in Energy
|
|
||||||
E = this.Calculator.calculateTotalEnergy(psi,Params,Transf,VDk,V);
|
|
||||||
E = E/Norm;
|
|
||||||
Observ.EVec = [Observ.EVec E];
|
|
||||||
|
|
||||||
%Chemical potential
|
|
||||||
Observ.mucVec = [Observ.mucVec muchem];
|
|
||||||
|
|
||||||
%Normalized residuals
|
|
||||||
res = this.Calculator.calculateNormalizedResiduals(psi,Params,Transf,VDk,V,muchem);
|
|
||||||
Observ.residual = [Observ.residual res];
|
|
||||||
|
|
||||||
Observ.res_idx = Observ.res_idx + 1;
|
|
||||||
|
|
||||||
save(sprintf('./Data/Run_%03i/psi_gs.mat',Params.njob),'psi','muchem','Observ','t_idx','Transf','Params','VDk','V');
|
|
||||||
|
|
||||||
%Adaptive time step -- Careful, this can quickly get out of control
|
|
||||||
relres = abs(Observ.residual(Observ.res_idx)-Observ.residual(Observ.res_idx-1))/Observ.residual(Observ.res_idx);
|
|
||||||
if relres <1e-5
|
|
||||||
if AdaptIdx > 4 && abs(dt) > Params.mindt
|
|
||||||
dt = dt / 2;
|
|
||||||
fprintf('Time step changed to '); disp(dt);
|
|
||||||
AdaptIdx = 0;
|
|
||||||
elseif AdaptIdx > 4 && abs(dt) < Params.mindt
|
|
||||||
break
|
|
||||||
else
|
|
||||||
AdaptIdx = AdaptIdx + 1;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
AdaptIdx = 0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if any(isnan(psi(:)))
|
|
||||||
disp('NaNs encountered!')
|
|
||||||
break
|
|
||||||
end
|
|
||||||
t_idx=t_idx+1;
|
|
||||||
pb.run(100*t_idx/Params.sim_time_cut_off);
|
|
||||||
end
|
|
||||||
|
|
||||||
%Change in Energy
|
|
||||||
E = this.Calculator.calculateTotalEnergy(psi,Params,Transf,VDk,V);
|
|
||||||
E = E/Norm;
|
|
||||||
Observ.EVec = [Observ.EVec E];
|
|
||||||
|
|
||||||
% Phase coherence
|
|
||||||
[PhaseC] = this.Calculator.calculatePhaseCoherence(psi,Transf,Params);
|
|
||||||
Observ.PCVec = [Observ.PCVec PhaseC];
|
|
||||||
|
|
||||||
Observ.res_idx = Observ.res_idx + 1;
|
|
||||||
|
|
||||||
pb.run(' - Job Completed!');
|
|
||||||
disp('Saving data...');
|
|
||||||
save(sprintf('./Data/Run_%03i/psi_gs.mat',Params.njob),'psi','muchem','Observ','t_idx','Transf','Params','VDk','V');
|
|
||||||
disp('Save complete!');
|
|
||||||
|
|
||||||
case 'RealTimeEvolution'
|
|
||||||
|
|
||||||
dt = abs(this.TimeStepSize);
|
|
||||||
|
|
||||||
KEop= 0.5*(Transf.KX.^2+Transf.KY.^2+Transf.KZ.^2);
|
|
||||||
|
|
||||||
muchem = this.Calculator.calculateChemicalPotential(psi,Params,Transf,VDk,V);
|
|
||||||
|
|
||||||
pb = Helper.ProgressBar();
|
|
||||||
pb.run('Running simulation in real time: ');
|
|
||||||
|
|
||||||
while t_idx < Params.sim_time_cut_off
|
|
||||||
|
|
||||||
% Parameters at time t
|
|
||||||
|
|
||||||
%kin
|
|
||||||
psi = fftn(psi);
|
|
||||||
psi = psi.*exp(-0.5*1i*dt*KEop);
|
|
||||||
psi = ifftn(psi);
|
|
||||||
|
|
||||||
%DDI
|
|
||||||
frho = fftn(abs(psi).^2);
|
|
||||||
Phi = real(ifftn(frho.*VDk));
|
|
||||||
|
|
||||||
%Real-space
|
|
||||||
psi = psi.*exp(-1i*dt*(V + Params.gs*abs(psi).^2 + Params.gammaQF*abs(psi).^3 + Params.gdd*Phi - muchem));
|
|
||||||
|
|
||||||
%kin
|
|
||||||
psi = fftn(psi);
|
|
||||||
psi = psi.*exp(-0.5*1i*dt*KEop);
|
|
||||||
psi = ifftn(psi);
|
|
||||||
|
|
||||||
muchem = this.Calculator.calculateChemicalPotential(psi,Params,Transf,VDk,V);
|
|
||||||
|
|
||||||
if mod(t_idx,1000)==0
|
|
||||||
%Change in Normalization
|
|
||||||
Norm = trapz(abs(psi(:)).^2)*Transf.dx*Transf.dy*Transf.dz; % normalisation
|
|
||||||
Observ.NormVec = [Observ.NormVec Norm];
|
|
||||||
|
|
||||||
%Change in Energy
|
|
||||||
E = this.Calculator.calculateTotalEnergy(psi,Params,Transf,VDk,V);
|
|
||||||
E = E/Norm;
|
|
||||||
Observ.EVec = [Observ.EVec E];
|
|
||||||
|
|
||||||
% Phase coherence
|
|
||||||
[PhaseC] = this.Calculator.calculatePhaseCoherence(psi,Transf);
|
|
||||||
Observ.PCVec = [Observ.PCVec PhaseC];
|
|
||||||
|
|
||||||
Observ.tVecPlot = [Observ.tVecPlot tVal];
|
|
||||||
Observ.res_idx = Observ.res_idx + 1;
|
|
||||||
|
|
||||||
save(sprintf('./Data/Run_%03i/TimeEvolution/psi_%i.mat',Params.njob,Observ.res_idx),'psi','muchem','Observ','t_idx');
|
|
||||||
end
|
|
||||||
if any(isnan(psi(:)))
|
|
||||||
disp('NaNs encountered!')
|
|
||||||
break
|
|
||||||
end
|
|
||||||
t_idx=t_idx+1;
|
|
||||||
pb.run(100*t_idx/Params.sim_time_cut_off);
|
|
||||||
end
|
|
||||||
|
|
||||||
%Change in Normalization
|
|
||||||
Norm = trapz(abs(psi(:)).^2)*Transf.dx*Transf.dy*Transf.dz; % normalisation
|
|
||||||
Observ.NormVec = [Observ.NormVec Norm];
|
|
||||||
|
|
||||||
%Change in Energy
|
|
||||||
E = this.Calculator.calculateTotalEnergy(psi,Params,Transf,VDk,V);
|
|
||||||
E = E/Norm;
|
|
||||||
Observ.EVec = [Observ.EVec E];
|
|
||||||
|
|
||||||
% Phase coherence
|
|
||||||
[PhaseC] = this.Calculator.calculatePhaseCoherence(psi,Transf);
|
|
||||||
Observ.PCVec = [Observ.PCVec PhaseC];
|
|
||||||
|
|
||||||
Observ.tVecPlot = [Observ.tVecPlot tVal];
|
|
||||||
Observ.res_idx = Observ.res_idx + 1;
|
|
||||||
|
|
||||||
pb.run(' - Job Completed!');
|
|
||||||
disp('Saving data...');
|
|
||||||
save(sprintf('./Data/Run_%03i/TimeEvolution/psi_%i.mat',Params.njob,Observ.res_idx),'psi','muchem','Observ','t_idx');
|
|
||||||
disp('Save complete!');
|
|
||||||
|
|
||||||
otherwise
|
|
||||||
disp('Choose a valid DDI cutoff type!')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,22 +0,0 @@
|
|||||||
function [Params, Transf, psi,V,VDk] = run(this)
|
|
||||||
% --- Obtain simulation parameters ---
|
|
||||||
[Params] = this.setupParameters();
|
|
||||||
this.SimulationParameters = Params;
|
|
||||||
|
|
||||||
% --- Set up spatial grids and transforms ---
|
|
||||||
[Transf] = this.setupSpace(Params);
|
|
||||||
[TransfRad] = this.setupSpaceRadial(Params);
|
|
||||||
|
|
||||||
% --- Initialize ---
|
|
||||||
mkdir(sprintf(this.SaveDirectory))
|
|
||||||
|
|
||||||
[psi,V,VDk] = this.initialize(Params,Transf,TransfRad);
|
|
||||||
|
|
||||||
Observ.EVec = []; Observ.NormVec = []; Observ.PCVec = []; Observ.tVecPlot = []; Observ.mucVec = [];
|
|
||||||
t_idx = 1; % Start at t = 0;
|
|
||||||
Observ.res_idx = 1;
|
|
||||||
|
|
||||||
% --- Run Simulation ---
|
|
||||||
mkdir(sprintf('./Data/Run_%03i',Params.njob))
|
|
||||||
[psi] = this.propagateWavefunction(psi,Params,Transf,VDk,V,t_idx,Observ);
|
|
||||||
end
|
|
@ -1,93 +0,0 @@
|
|||||||
function [Params] = setupParameters(this)
|
|
||||||
CONSTANTS = Helper.PhysicsConstants;
|
|
||||||
hbar = CONSTANTS.PlanckConstantReduced; % [J.s]
|
|
||||||
kbol = CONSTANTS.BoltzmannConstant; % [J/K]
|
|
||||||
mu0 = CONSTANTS.VacuumPermeability; % [N/A^2]
|
|
||||||
muB = CONSTANTS.BohrMagneton; % [J/T]
|
|
||||||
a0 = CONSTANTS.BohrRadius; % [m]
|
|
||||||
m0 = CONSTANTS.AtomicMassUnit; % [kg]
|
|
||||||
w0 = 2*pi*100; % Angular frequency unit [s^-1]
|
|
||||||
mu0factor = 0.3049584233607396; % =(m0/me)*pi*alpha^2 -- me=mass of electron, alpha=fine struct. const.
|
|
||||||
% mu0=mu0factor *hbar^2*a0/(m0*muB^2)
|
|
||||||
% Number of points in each direction
|
|
||||||
Params.Nx = this.NumberOfGridPoints(1);
|
|
||||||
Params.Ny = this.NumberOfGridPoints(2);
|
|
||||||
Params.Nz = this.NumberOfGridPoints(3);
|
|
||||||
|
|
||||||
% Dimensions (in units of l0)
|
|
||||||
Params.Lx = this.Dimensions(1);
|
|
||||||
Params.Ly = this.Dimensions(2);
|
|
||||||
Params.Lz = this.Dimensions(3);
|
|
||||||
|
|
||||||
% Mass, length scale
|
|
||||||
Params.m = CONSTANTS.Dy164Mass;
|
|
||||||
l0 = sqrt(hbar/(Params.m*w0)); % Defining a harmonic oscillator length
|
|
||||||
|
|
||||||
% Atom numbers
|
|
||||||
Params.N = this.NumberOfAtoms;
|
|
||||||
|
|
||||||
% Dipole angle
|
|
||||||
Params.theta = this.DipolarPolarAngle; % pi/2 dipoles along x, theta=0 dipoles along z
|
|
||||||
Params.phi = this.DipolarAzimuthAngle;
|
|
||||||
|
|
||||||
% Dipole lengths (units of muB)
|
|
||||||
Params.mu = CONSTANTS.DyMagneticMoment;
|
|
||||||
|
|
||||||
% Scattering lengths
|
|
||||||
Params.as = this.ScatteringLength*a0;
|
|
||||||
|
|
||||||
% Trapping frequencies
|
|
||||||
Params.wx = 2*pi*this.TrapFrequencies(1);
|
|
||||||
Params.wy = 2*pi*this.TrapFrequencies(2);
|
|
||||||
Params.wz = 2*pi*this.TrapFrequencies(3);
|
|
||||||
|
|
||||||
% Stochastic GPE
|
|
||||||
Params.gamma_S = 7.5*10^(-3); % gamma for the stochastic GPE
|
|
||||||
Params.muchem = 12.64*Params.wz/w0; % fixing the chemical potential for the stochastic GPE
|
|
||||||
|
|
||||||
Params.Etol = this.EnergyTolerance; % Tolerances
|
|
||||||
Params.sim_time_cut_off = this.NumberOfTimeSteps; % sometimes the imaginary time gets a little stuck
|
|
||||||
% even though the solution is good, this just stops it going on forever
|
|
||||||
Params.mindt = this.MinimumTimeStepSize; % Minimum size for a time step using adaptive dt
|
|
||||||
|
|
||||||
Params.njob = this.JobNumber;
|
|
||||||
|
|
||||||
% ================ Parameters defined by those above ================ %
|
|
||||||
|
|
||||||
% Contact interaction strength (units of l0/m)
|
|
||||||
Params.gs = 4*pi*Params.as/l0;
|
|
||||||
|
|
||||||
% Dipole lengths
|
|
||||||
Params.add = mu0*Params.mu^2*Params.m/(12*pi*hbar^2);
|
|
||||||
|
|
||||||
% DDI strength
|
|
||||||
Params.gdd = 12*pi*Params.add/l0; %sometimes the 12 is a 4 --> depends on how Vdk (DDI) is defined
|
|
||||||
|
|
||||||
% Trap gamma
|
|
||||||
Params.gx = (Params.wx/w0)^2;
|
|
||||||
Params.gy = (Params.wy/w0)^2;
|
|
||||||
Params.gz = (Params.wz/w0)^2;
|
|
||||||
|
|
||||||
% == Calculate LHY correction == %
|
|
||||||
eps_dd = Params.add/Params.as;
|
|
||||||
if eps_dd == 0
|
|
||||||
Q5 = 1;
|
|
||||||
elseif eps_dd == 1
|
|
||||||
Q5 = 3*sqrt(3)/2;
|
|
||||||
else
|
|
||||||
yeps = (1-eps_dd)/(3*eps_dd);
|
|
||||||
Q5 = (3*eps_dd)^(5/2)*( (8+26*yeps+33*yeps^2)*sqrt(1+yeps) + 15*yeps^3*log((1+sqrt(1+yeps))/sqrt(yeps)) )/48;
|
|
||||||
Q5 = real(Q5);
|
|
||||||
end
|
|
||||||
|
|
||||||
Params.gammaQF = 128/3*sqrt(pi*(Params.as/l0)^5)*Q5;
|
|
||||||
|
|
||||||
% Loading the rest into Params
|
|
||||||
Params.hbar = hbar;
|
|
||||||
Params.kbol = kbol;
|
|
||||||
Params.mu0 = mu0;
|
|
||||||
Params.muB = muB;
|
|
||||||
Params.a0 = a0;
|
|
||||||
Params.w0 = w0;
|
|
||||||
Params.l0 = l0;
|
|
||||||
end
|
|
@ -1,33 +0,0 @@
|
|||||||
function [Transf] = setupSpace(~,Params)
|
|
||||||
Transf.Xmax = 0.5*Params.Lx;
|
|
||||||
Transf.Ymax = 0.5*Params.Ly;
|
|
||||||
Transf.Zmax = 0.5*Params.Lz;
|
|
||||||
|
|
||||||
Nz = Params.Nz; Nx = Params.Nx; Ny = Params.Ny;
|
|
||||||
|
|
||||||
% Fourier grids
|
|
||||||
x = linspace(-0.5*Params.Lx,0.5*Params.Lx-Params.Lx/Params.Nx,Params.Nx);
|
|
||||||
Kmax = pi*Params.Nx/Params.Lx;
|
|
||||||
kx = linspace(-Kmax,Kmax,Nx+1);
|
|
||||||
kx = kx(1:end-1); dkx = kx(2)-kx(1);
|
|
||||||
kx = fftshift(kx);
|
|
||||||
|
|
||||||
y = linspace(-0.5*Params.Ly,0.5*Params.Ly-Params.Ly/Params.Ny,Params.Ny);
|
|
||||||
Kmax = pi*Params.Ny/Params.Ly;
|
|
||||||
ky = linspace(-Kmax,Kmax,Ny+1);
|
|
||||||
ky = ky(1:end-1); dky = ky(2)-ky(1);
|
|
||||||
ky = fftshift(ky);
|
|
||||||
|
|
||||||
z = linspace(-0.5*Params.Lz,0.5*Params.Lz-Params.Lz/Params.Nz,Params.Nz);
|
|
||||||
Kmax = pi*Params.Nz/Params.Lz;
|
|
||||||
kz = linspace(-Kmax,Kmax,Nz+1);
|
|
||||||
kz = kz(1:end-1); dkz = kz(2)-kz(1);
|
|
||||||
kz = fftshift(kz);
|
|
||||||
|
|
||||||
[Transf.X,Transf.Y,Transf.Z]=ndgrid(x,y,z);
|
|
||||||
[Transf.KX,Transf.KY,Transf.KZ]=ndgrid(kx,ky,kz);
|
|
||||||
Transf.x = x; Transf.y = y; Transf.z = z;
|
|
||||||
Transf.kx = kx; Transf.ky = ky; Transf.kz = kz;
|
|
||||||
Transf.dx = x(2)-x(1); Transf.dy = y(2)-y(1); Transf.dz = z(2)-z(1);
|
|
||||||
Transf.dkx = dkx; Transf.dky = dky; Transf.dkz = dkz;
|
|
||||||
end
|
|
@ -1,310 +0,0 @@
|
|||||||
function [Transf] = setupSpaceRadial(~,Params,morder)
|
|
||||||
|
|
||||||
Params.Lr = 0.5*min(Params.Lx,Params.Ly);
|
|
||||||
Params.Nr = max(Params.Nx,Params.Ny);
|
|
||||||
|
|
||||||
Zmax = 0.5*Params.Lz;
|
|
||||||
Rmax = Params.Lr;
|
|
||||||
Nz = Params.Nz;
|
|
||||||
Nr = Params.Nr;
|
|
||||||
|
|
||||||
if(nargin==2)
|
|
||||||
morder=0; %only do Bessel J0
|
|
||||||
end
|
|
||||||
|
|
||||||
% Fourier grids
|
|
||||||
z=linspace(-Zmax,Zmax,Nz+1);
|
|
||||||
z=z(1:end-1);
|
|
||||||
dz=z(2)-z(1);
|
|
||||||
Kmax=Nz*2*pi/(4*Zmax);
|
|
||||||
kz=linspace(-Kmax,Kmax,Nz+1);
|
|
||||||
kz=kz(1:end-1);
|
|
||||||
|
|
||||||
% Hankel grids and transform
|
|
||||||
H = hankelmatrix(morder,Rmax,Nr);
|
|
||||||
r=H.r(:);
|
|
||||||
kr=H.kr(:);
|
|
||||||
T = diag(H.J/H.kmax)*H.T*diag(Rmax./H.J)*dz*(2*pi);
|
|
||||||
Tinv = diag(H.J./Rmax)*H.T'*diag(H.kmax./H.J)/dz/(2*pi);
|
|
||||||
wr=H.wr;
|
|
||||||
wk=H.wk;
|
|
||||||
% H.T'*diag(H.J/H.vmax)*H.T*diag(Rmax./H.J)
|
|
||||||
|
|
||||||
[Transf.R,Transf.Z]=ndgrid(r,z);
|
|
||||||
[Transf.KR,Transf.KZ]=ndgrid(kr,kz);
|
|
||||||
Transf.T=T;
|
|
||||||
Transf.Tinv=Tinv;
|
|
||||||
Transf.r=r;
|
|
||||||
Transf.kr=kr;
|
|
||||||
Transf.z=z;
|
|
||||||
Transf.kz=kz;
|
|
||||||
Transf.wr=wr;
|
|
||||||
Transf.wk=wk;
|
|
||||||
Transf.Rmax=Rmax;
|
|
||||||
Transf.Zmax=Zmax;
|
|
||||||
Transf.dz=z(2)-z(1);
|
|
||||||
Transf.dkz=kz(2)-kz(1);
|
|
||||||
|
|
||||||
function s_HT = hankelmatrix(order,rmax,Nr,eps_roots)
|
|
||||||
%HANKEL_MATRIX: Generates data to use for Hankel Transforms
|
|
||||||
%
|
|
||||||
% s_HT = hankel_matrix(order, rmax, Nr, eps_roots)
|
|
||||||
%
|
|
||||||
% s_HT = Structure containing data to use for the pQDHT
|
|
||||||
% order = Transform order
|
|
||||||
% rmax = Radial extent of transform
|
|
||||||
% Nr = Number of sample points
|
|
||||||
% eps_roots = Error in estimation of roots of Bessel function (optional)
|
|
||||||
%
|
|
||||||
% s_HT:
|
|
||||||
% order, rmax, Nr = As above
|
|
||||||
% J_roots = Roots of the pth order Bessel fn.
|
|
||||||
% J_roots_N1 = (N+1)th root
|
|
||||||
% r = Radial co-ordinate vector
|
|
||||||
% v = frequency co-ordinate vector
|
|
||||||
% kr = Radial wave number co-ordinate vector
|
|
||||||
% vmax = Limiting frequency
|
|
||||||
% = roots_N1 / (2*pi*rmax)
|
|
||||||
% S = rmax * 2*pi*vmax (S product)
|
|
||||||
% T = Transform matrix
|
|
||||||
% J = Scaling vector
|
|
||||||
% = J_(order+1){roots}
|
|
||||||
%
|
|
||||||
% The algorithm used is that from:
|
|
||||||
% "Computation of quasi-discrete Hankel transforms of the integer
|
|
||||||
% order for propagating optical wave fields"
|
|
||||||
% Manuel Guizar-Sicairos and Julio C. Guitierrez-Vega
|
|
||||||
% J. Opt. Soc. Am. A 21(1) 53-58 (2004)
|
|
||||||
%
|
|
||||||
% The algorithm also calls the function:
|
|
||||||
% zn = bessel_zeros(1, p, Nr+1, 1e-6),
|
|
||||||
% where p and N are defined above, to calculate the roots of the bessel
|
|
||||||
% function. This algorithm is taken from:
|
|
||||||
% "An Algorithm with ALGOL 60 Program for the Computation of the
|
|
||||||
% zeros of the Ordinary Bessel Functions and those of their
|
|
||||||
% Derivatives".
|
|
||||||
% N. M. Temme
|
|
||||||
% Journal of Computational Physics, 32, 270-279 (1979)
|
|
||||||
%
|
|
||||||
% Example: Propagation of radial field
|
|
||||||
%
|
|
||||||
% % Note the use of matrix and element products / divisions
|
|
||||||
% H = hankel_matrix(0, 1e-3, 512);
|
|
||||||
% DR0 = 50e-6;
|
|
||||||
% Ur0 = exp(-(H.r/DR0).^2);
|
|
||||||
% Ukr0 = H.T * (Ur0./H.J);
|
|
||||||
% k0 = 2*pi/800e-9;
|
|
||||||
% kz = realsqrt((k0^2 - H.kr.^2).*(k0>H.kr));
|
|
||||||
% z = (-5e-3:1e-5:5e-3);
|
|
||||||
% Ukrz = (Ukr0*ones(1,length(z))).*exp(i*kz*z);
|
|
||||||
% Urz = (H.T * Ukrz) .* (H.J * ones(1,length(z)));
|
|
||||||
%
|
|
||||||
% See also bessel_zeros, besselj
|
|
||||||
|
|
||||||
if (~exist('eps_roots', 'var')||isemtpy(eps_roots))
|
|
||||||
s_HT.eps_roots = 1e-6;
|
|
||||||
else
|
|
||||||
s_HT.eps_roots = eps_roots;
|
|
||||||
end
|
|
||||||
|
|
||||||
s_HT.order = order;
|
|
||||||
s_HT.rmax = rmax;
|
|
||||||
s_HT.Nr = Nr;
|
|
||||||
|
|
||||||
% Calculate N+1 roots:
|
|
||||||
J_roots = bessel_zeros(1, s_HT.order, s_HT.Nr+1, s_HT.eps_roots);
|
|
||||||
s_HT.J_roots = J_roots(1:end-1);
|
|
||||||
s_HT.J_roots_N1 = J_roots(end);
|
|
||||||
|
|
||||||
% Calculate co-ordinate vectors
|
|
||||||
s_HT.r = s_HT.J_roots * s_HT.rmax / s_HT.J_roots_N1;
|
|
||||||
s_HT.v = s_HT.J_roots / (2*pi * s_HT.rmax);
|
|
||||||
s_HT.kr = 2*pi * s_HT.v;
|
|
||||||
s_HT.kmax = s_HT.J_roots_N1 / (s_HT.rmax);
|
|
||||||
s_HT.vmax = s_HT.J_roots_N1 / (2*pi * s_HT.rmax);
|
|
||||||
s_HT.S = s_HT.J_roots_N1;
|
|
||||||
|
|
||||||
% Calculate hankel matrix and vectors
|
|
||||||
% I use (p=order) and (p1=order+1)
|
|
||||||
Jp = besselj(s_HT.order, (s_HT.J_roots) * (s_HT.J_roots.') / s_HT.S);
|
|
||||||
Jp1 = abs(besselj(s_HT.order+1, s_HT.J_roots));
|
|
||||||
s_HT.T = 2*Jp./(Jp1 * (Jp1.') * s_HT.S);
|
|
||||||
s_HT.J = Jp1;
|
|
||||||
s_HT.wr=2./((s_HT.kmax)^2*abs(Jp1).^2);
|
|
||||||
s_HT.wk=2./((s_HT.rmax)^2*abs(Jp1).^2);
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
function z = bessel_zeros(d,a,n,e)
|
|
||||||
%BESSEL_ZEROS: Finds the first n zeros of a bessel function
|
|
||||||
%
|
|
||||||
% z = bessel_zeros(d, a, n, e)
|
|
||||||
%
|
|
||||||
% z = zeros of the bessel function
|
|
||||||
% d = Bessel function type:
|
|
||||||
% 1: Ja
|
|
||||||
% 2: Ya
|
|
||||||
% 3: Ja'
|
|
||||||
% 4: Ya'
|
|
||||||
% a = Bessel order (a>=0)
|
|
||||||
% n = Number of zeros to find
|
|
||||||
% e = Relative error in root
|
|
||||||
%
|
|
||||||
% This function uses the routine described in:
|
|
||||||
% "An Algorithm with ALGOL 60 Program for the Computation of the
|
|
||||||
% zeros of the Ordinary Bessel Functions and those of their
|
|
||||||
% Derivatives".
|
|
||||||
% N. M. Temme
|
|
||||||
% Journal of Computational Physics, 32, 270-279 (1979)
|
|
||||||
|
|
||||||
z = zeros(n, 1);
|
|
||||||
aa = a^2;
|
|
||||||
mu = 4*aa;
|
|
||||||
mu2 = mu^2;
|
|
||||||
mu3 = mu^3;
|
|
||||||
mu4 = mu^4;
|
|
||||||
|
|
||||||
if (d<3)
|
|
||||||
p = 7*mu - 31;
|
|
||||||
p0 = mu - 1;
|
|
||||||
if ((1+p)==p)
|
|
||||||
p1 = 0;
|
|
||||||
q1 = 0;
|
|
||||||
else
|
|
||||||
p1 = 4*(253*mu2 - 3722*mu+17869)*p0/(15*p);
|
|
||||||
q1 = 1.6*(83*mu2 - 982*mu + 3779)/p;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
p = 7*mu2 + 82*mu - 9;
|
|
||||||
p0 = mu + 3;
|
|
||||||
if ((p+1)==1)
|
|
||||||
p1 = 0;
|
|
||||||
q1 = 0;
|
|
||||||
else
|
|
||||||
p1 = (4048*mu4 + 131264*mu3 - 221984*mu2 - 417600*mu + 1012176)/(60*p);
|
|
||||||
q1 = 1.6*(83*mu3 + 2075*mu2 - 3039*mu + 3537)/p;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if (d==1)|(d==4)
|
|
||||||
t = .25;
|
|
||||||
else
|
|
||||||
t = .75;
|
|
||||||
end
|
|
||||||
tt = 4*t;
|
|
||||||
|
|
||||||
if (d<3)
|
|
||||||
pp1 = 5/48;
|
|
||||||
qq1 = -5/36;
|
|
||||||
else
|
|
||||||
pp1 = -7/48;
|
|
||||||
qq1 = 35/288;
|
|
||||||
end
|
|
||||||
|
|
||||||
y = .375*pi;
|
|
||||||
if (a>=3)
|
|
||||||
bb = a^(-2/3);
|
|
||||||
else
|
|
||||||
bb = 1;
|
|
||||||
end
|
|
||||||
a1 = 3*a - 8;
|
|
||||||
% psi = (.5*a + .25)*pi;
|
|
||||||
|
|
||||||
for s=1:n
|
|
||||||
if ((a==0)&(s==1)&(d==3))
|
|
||||||
x = 0;
|
|
||||||
j = 0;
|
|
||||||
else
|
|
||||||
if (s>=a1)
|
|
||||||
b = (s + .5*a - t)*pi;
|
|
||||||
c = .015625/(b^2);
|
|
||||||
x = b - .125*(p0 - p1*c)/(b*(1 - q1*c));
|
|
||||||
else
|
|
||||||
if (s==1)
|
|
||||||
switch (d)
|
|
||||||
case (1)
|
|
||||||
x = -2.33811;
|
|
||||||
case (2)
|
|
||||||
x = -1.17371;
|
|
||||||
case (3)
|
|
||||||
x = -1.01879;
|
|
||||||
otherwise
|
|
||||||
x = -2.29444;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
x = y*(4*s - tt);
|
|
||||||
v = x^(-2);
|
|
||||||
x = -x^(2/3) * (1 + v*(pp1 + qq1*v));
|
|
||||||
end
|
|
||||||
u = x*bb;
|
|
||||||
v = fi(2/3 * (-u)^1.5);
|
|
||||||
w = 1/cos(v);
|
|
||||||
xx = 1 - w^2;
|
|
||||||
c = sqrt(u/xx);
|
|
||||||
if (d<3)
|
|
||||||
x = w*(a + c*(-5/u - c*(6 - 10/xx))/(48*a*u));
|
|
||||||
else
|
|
||||||
x = w*(a + c*(7/u + c*(18 - 14/xx))/(48*a*u));
|
|
||||||
end
|
|
||||||
end
|
|
||||||
j = 0;
|
|
||||||
|
|
||||||
while ((j==0)|((j<5)&(abs(w/x)>e)))
|
|
||||||
xx = x^2;
|
|
||||||
x4 = x^4;
|
|
||||||
a2 = aa - xx;
|
|
||||||
r0 = bessr(d, a, x);
|
|
||||||
j = j+1;
|
|
||||||
if (d<3)
|
|
||||||
u = r0;
|
|
||||||
w = 6*x*(2*a + 1);
|
|
||||||
p = (1 - 4*a2)/w;
|
|
||||||
q = (4*(xx-mu) - 2 - 12*a)/w;
|
|
||||||
else
|
|
||||||
u = -xx*r0/a2;
|
|
||||||
v = 2*x*a2/(3*(aa+xx));
|
|
||||||
w = 64*a2^3;
|
|
||||||
q = 2*v*(1 + mu2 + 32*mu*xx + 48*x4)/w;
|
|
||||||
p = v*(1 + (40*mu*xx + 48*x4 - mu2)/w);
|
|
||||||
end
|
|
||||||
w = u*(1 + p*r0)/(1 + q*r0);
|
|
||||||
x = x+w;
|
|
||||||
end
|
|
||||||
z(s) = x;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function FI = fi(y)
|
|
||||||
c1 = 1.570796;
|
|
||||||
if (~y)
|
|
||||||
FI = 0;
|
|
||||||
elseif (y>1e5)
|
|
||||||
FI = c1;
|
|
||||||
else
|
|
||||||
if (y<1)
|
|
||||||
p = (3*y)^(1/3);
|
|
||||||
pp = p^2;
|
|
||||||
p = p*(1 + pp*(pp*(27 - 2*pp) - 210)/1575);
|
|
||||||
else
|
|
||||||
p = 1/(y + c1);
|
|
||||||
pp = p^2;
|
|
||||||
p = c1 - p*(1 + pp*(2310 + pp*(3003 + pp*(4818 + pp*(8591 + pp*16328))))/3465);
|
|
||||||
end
|
|
||||||
pp = (y+p)^2;
|
|
||||||
r = (p - atan(p+y))/pp;
|
|
||||||
FI = p - (1+pp)*r*(1 + r/(p+y));
|
|
||||||
end
|
|
||||||
return
|
|
||||||
|
|
||||||
function Jr = bessr(d,a,x)
|
|
||||||
switch (d)
|
|
||||||
case (1)
|
|
||||||
Jr = besselj(a, x)./besselj(a+1, x);
|
|
||||||
case (2)
|
|
||||||
Jr = bessely(a, x)./bessely(a+1, x);
|
|
||||||
case (3)
|
|
||||||
Jr = a./x - besselj(a+1, x)./besselj(a, x);
|
|
||||||
otherwise
|
|
||||||
Jr = a./x - bessely(a+1, x)./bessely(a, x);
|
|
||||||
end
|
|
||||||
return
|
|
@ -1,25 +0,0 @@
|
|||||||
function [psi] = setupWavefunction(~,Params,Transf)
|
|
||||||
|
|
||||||
X = Transf.X; Y = Transf.Y; Z = Transf.Z;
|
|
||||||
|
|
||||||
ellx = sqrt(Params.hbar/(Params.m*Params.wx))/Params.l0;
|
|
||||||
elly = sqrt(Params.hbar/(Params.m*Params.wy))/Params.l0;
|
|
||||||
ellz = sqrt(Params.hbar/(Params.m*Params.wz))/Params.l0;
|
|
||||||
|
|
||||||
Rx = 8*ellx; Ry = 8*elly; Rz = 8*ellz;
|
|
||||||
X0 = 0.0*Transf.Xmax; Y0 = 0.0*Transf.Ymax; Z0 = 0*Transf.Zmax;
|
|
||||||
|
|
||||||
psi = exp(-(X-X0).^2/Rx^2-(Y-Y0).^2/Ry^2-(Z-Z0).^2/Rz^2);
|
|
||||||
cur_norm = trapz(abs(psi(:)).^2)*Transf.dx*Transf.dy*Transf.dz;
|
|
||||||
psi = psi/sqrt(cur_norm);
|
|
||||||
|
|
||||||
% add some noise
|
|
||||||
r = normrnd(0,1,size(X));
|
|
||||||
theta = rand(size(X));
|
|
||||||
noise = r.*exp(2*pi*1i*theta);
|
|
||||||
psi = psi + 0.01*noise;
|
|
||||||
|
|
||||||
Norm = trapz(abs(psi(:)).^2)*Transf.dx*Transf.dy*Transf.dz;
|
|
||||||
psi = sqrt(Params.N)*psi/sqrt(Norm);
|
|
||||||
|
|
||||||
end
|
|
@ -1,174 +0,0 @@
|
|||||||
classdef Potentials < handle & matlab.mixin.Copyable
|
|
||||||
|
|
||||||
properties (Access = private)
|
|
||||||
|
|
||||||
PotentialDefaults = struct('TrapPotentialType', 'Harmonic', ...
|
|
||||||
'TrapFrequencies', 100 * ones(1,3), ...
|
|
||||||
'TrapDepth', 10, ...
|
|
||||||
'BoxSize', 5);
|
|
||||||
end
|
|
||||||
|
|
||||||
properties (Access = public)
|
|
||||||
TrapPotentialType;
|
|
||||||
TrapFrequencies;
|
|
||||||
TrapDepth;
|
|
||||||
BoxSize;
|
|
||||||
NumberOfGridPoints;
|
|
||||||
Dimensions;
|
|
||||||
SimulationParameters;
|
|
||||||
end
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
%- Methods
|
|
||||||
|
|
||||||
methods
|
|
||||||
function this = Potentials(varargin)
|
|
||||||
|
|
||||||
p = inputParser;
|
|
||||||
p.KeepUnmatched = true;
|
|
||||||
|
|
||||||
addParameter(p, 'TrapPotentialType', this.PotentialDefaults.TrapPotentialType,...
|
|
||||||
@(x) assert(any(strcmpi(x,{'None','Harmonic','SquareBox','RoundBox'}))));
|
|
||||||
addParameter(p, 'TrapFrequencies', this.PotentialDefaults.TrapFrequencies,...
|
|
||||||
@(x) assert(isnumeric(x) && isvector(x) && all(x > 0)));
|
|
||||||
addParameter(p, 'TrapDepth', this.PotentialDefaults.TrapDepth,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
|
|
||||||
addParameter(p, 'BoxSize', this.PotentialDefaults.BoxSize,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
|
|
||||||
addParameter(p, 'NumberOfGridPoints', 128 * ones(1,3),...
|
|
||||||
@(x) assert(isnumeric(x) && isvector(x) && all(x > 0)));
|
|
||||||
addParameter(p, 'Dimensions', 10 * ones(1,3),...
|
|
||||||
@(x) assert(isnumeric(x) && isvector(x) && all(x > 0)));
|
|
||||||
|
|
||||||
p.parse(varargin{:});
|
|
||||||
|
|
||||||
this.TrapPotentialType = p.Results.TrapPotentialType;
|
|
||||||
this.TrapFrequencies = p.Results.TrapFrequencies;
|
|
||||||
this.TrapDepth = p.Results.TrapDepth;
|
|
||||||
this.BoxSize = p.Results.BoxSize;
|
|
||||||
this.NumberOfGridPoints = p.Results.NumberOfGridPoints;
|
|
||||||
this.Dimensions = p.Results.Dimensions;
|
|
||||||
|
|
||||||
this.SimulationParameters = this.setupParameters();
|
|
||||||
end
|
|
||||||
|
|
||||||
function [ret] = trap(this)
|
|
||||||
format long
|
|
||||||
switch this.TrapPotentialType
|
|
||||||
case 'None'
|
|
||||||
x = linspace(-0.5*this.SimulationParameters.Lx,0.5*this.SimulationParameters.Lx-this.SimulationParameters.Lx/this.SimulationParameters.Nx,this.SimulationParameters.Nx);
|
|
||||||
y = linspace(-0.5*this.SimulationParameters.Ly,0.5*this.SimulationParameters.Ly-this.SimulationParameters.Ly/this.SimulationParameters.Ny,this.SimulationParameters.Ny);
|
|
||||||
z = linspace(-0.5*this.SimulationParameters.Lz,0.5*this.SimulationParameters.Lz-this.SimulationParameters.Lz/this.SimulationParameters.Nz,this.SimulationParameters.Nz);
|
|
||||||
[X,Y,Z] = ndgrid(x,y,z);
|
|
||||||
ret = 0.0 * (X+Y+Z);
|
|
||||||
case 'Harmonic'
|
|
||||||
x = linspace(-0.5*this.SimulationParameters.Lx,0.5*this.SimulationParameters.Lx-this.SimulationParameters.Lx/this.SimulationParameters.Nx,this.SimulationParameters.Nx);
|
|
||||||
y = linspace(-0.5*this.SimulationParameters.Ly,0.5*this.SimulationParameters.Ly-this.SimulationParameters.Ly/this.SimulationParameters.Ny,this.SimulationParameters.Ny);
|
|
||||||
z = linspace(-0.5*this.SimulationParameters.Lz,0.5*this.SimulationParameters.Lz-this.SimulationParameters.Lz/this.SimulationParameters.Nz,this.SimulationParameters.Nz);
|
|
||||||
[X,Y,Z] = ndgrid(x,y,z);
|
|
||||||
ret = 0.5*(this.SimulationParameters.gx.*X.^2+this.SimulationParameters.gy.*Y.^2+this.SimulationParameters.gz*Z.^2);
|
|
||||||
case 'SquareBox'
|
|
||||||
x = linspace(-0.5*this.SimulationParameters.Lx,0.5*this.SimulationParameters.Lx-this.SimulationParameters.Lx/this.SimulationParameters.Nx,this.SimulationParameters.Nx);
|
|
||||||
y = linspace(-0.5*this.SimulationParameters.Ly,0.5*this.SimulationParameters.Ly-this.SimulationParameters.Ly/this.SimulationParameters.Ny,this.SimulationParameters.Ny);
|
|
||||||
z = linspace(-0.5*this.SimulationParameters.Lz,0.5*this.SimulationParameters.Lz-this.SimulationParameters.Lz/this.SimulationParameters.Nz,this.SimulationParameters.Nz);
|
|
||||||
[X,Y,Z] = ndgrid(x,y,z);
|
|
||||||
|
|
||||||
heaviside_X = this.custom_heaviside(-abs(X) + this.SimulationParameters.boxsize/2);
|
|
||||||
heaviside_Y = this.custom_heaviside(-abs(Y) + this.SimulationParameters.boxsize/2);
|
|
||||||
heaviside_Z = this.custom_heaviside(-abs(Z) + this.SimulationParameters.boxsize/2);
|
|
||||||
|
|
||||||
ret = this.SimulationParameters.boxdepth * (1 - heaviside_X .* heaviside_Y .* heaviside_Z);
|
|
||||||
case 'RoundBox'
|
|
||||||
x = linspace(-0.5*this.SimulationParameters.Lx,0.5*this.SimulationParameters.Lx-this.SimulationParameters.Lx/this.SimulationParameters.Nx,this.SimulationParameters.Nx);
|
|
||||||
y = linspace(-0.5*this.SimulationParameters.Ly,0.5*this.SimulationParameters.Ly-this.SimulationParameters.Ly/this.SimulationParameters.Ny,this.SimulationParameters.Ny);
|
|
||||||
z = linspace(-0.5*this.SimulationParameters.Lz,0.5*this.SimulationParameters.Lz-this.SimulationParameters.Lz/this.SimulationParameters.Nz,this.SimulationParameters.Nz);
|
|
||||||
[X,Y,Z] = ndgrid(x,y,z);
|
|
||||||
|
|
||||||
ret = this.SimulationParameters.boxdepth * (1 - this.custom_heaviside((this.SimulationParameters.boxsize/2)^2 - X.^2 - Y.^2 - Z.^2));
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function restoreDefaults(this)
|
|
||||||
this.TrapPotentialType = this.PotentialDefaults.TrapPotentialType;
|
|
||||||
this.TrapFrequencies = this.PotentialDefaults.TrapFrequencies;
|
|
||||||
end
|
|
||||||
end %
|
|
||||||
|
|
||||||
methods
|
|
||||||
function set.TrapFrequencies(this, val)
|
|
||||||
assert(isnumeric(val) && isvector(val) && all(val > 0), 'Incorrectly defined trap frequencies!');
|
|
||||||
this.TrapFrequencies = val;
|
|
||||||
end
|
|
||||||
function ret = get.TrapFrequencies(this)
|
|
||||||
ret = this.TrapFrequencies;
|
|
||||||
end
|
|
||||||
function set.TrapPotentialType(this, val)
|
|
||||||
assert(any(strcmpi(val,{'None','Harmonic','SquareBox','RoundBox'})), 'Trap potential of the specified type cannot be generated!');
|
|
||||||
this.TrapPotentialType = val;
|
|
||||||
end
|
|
||||||
function ret = get.TrapPotentialType(this)
|
|
||||||
ret = this.TrapPotentialType;
|
|
||||||
end
|
|
||||||
function set.NumberOfGridPoints(this, val)
|
|
||||||
assert(isnumeric(val) && isvector(val) && all(val > 0), 'Incorrectly defined grid!');
|
|
||||||
this.NumberOfGridPoints = val;
|
|
||||||
end
|
|
||||||
function ret = get.NumberOfGridPoints(this)
|
|
||||||
ret = this.NumberOfGridPoints;
|
|
||||||
end
|
|
||||||
function set.Dimensions(this, val)
|
|
||||||
assert(isnumeric(val) && isvector(val) && all(val > 0), 'Incorrectly defined dimensions!');
|
|
||||||
this.Dimensions = val;
|
|
||||||
end
|
|
||||||
function ret = get.Dimensions(this)
|
|
||||||
ret = this.Dimensions;
|
|
||||||
end
|
|
||||||
end % - setters and getters
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
%- Methods
|
|
||||||
|
|
||||||
methods(Access = protected)
|
|
||||||
function cp = copyElement(this)
|
|
||||||
% Shallow copy object
|
|
||||||
cp = copyElement@matlab.mixin.Copyable(this);
|
|
||||||
|
|
||||||
% Forces the setter to redefine the function handles to the new copied object
|
|
||||||
|
|
||||||
pl = properties(this);
|
|
||||||
for k = 1:length(pl)
|
|
||||||
sc = superclasses(this.(pl{k}));
|
|
||||||
if any(contains(sc,{'matlab.mixin.Copyable'}))
|
|
||||||
cp.(pl{k}) = this.(pl{k}).copy();
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
methods (Static)
|
|
||||||
|
|
||||||
function y = custom_heaviside(x)
|
|
||||||
% This function computes the Heaviside step function with a custom value for Heaviside(0).
|
|
||||||
% x: input array
|
|
||||||
% H0: value for Heaviside(0)
|
|
||||||
|
|
||||||
% Use MATLAB's built-in heaviside function
|
|
||||||
y = heaviside(x);
|
|
||||||
|
|
||||||
% Replace the default value for Heaviside(0) with the custom value H0
|
|
||||||
y(x == 0) = 1;
|
|
||||||
end
|
|
||||||
|
|
||||||
% Creates an Instance of Class, ensures singleton behaviour (that there
|
|
||||||
% can only be one Instance of this class
|
|
||||||
function singleObj = getInstance(varargin)
|
|
||||||
% Creates an Instance of Class, ensures singleton behaviour
|
|
||||||
persistent localObj;
|
|
||||||
if isempty(localObj) || ~isvalid(localObj)
|
|
||||||
localObj = Simulator.Potentials(varargin{:});
|
|
||||||
end
|
|
||||||
singleObj = localObj;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,36 +0,0 @@
|
|||||||
function [Params] = setupParameters(this)
|
|
||||||
CONSTANTS = Helper.PhysicsConstants;
|
|
||||||
hbar = CONSTANTS.PlanckConstantReduced; % [J.s]
|
|
||||||
w0 = 2*pi*100; % Angular frequency unit [s^-1]
|
|
||||||
|
|
||||||
% Mass, length scale
|
|
||||||
Params.m = CONSTANTS.Dy164Mass;
|
|
||||||
l0 = sqrt(hbar/(Params.m*w0)); % Defining a harmonic oscillator length
|
|
||||||
|
|
||||||
% Number of points in each direction
|
|
||||||
Params.Nx = this.NumberOfGridPoints(1);
|
|
||||||
Params.Ny = this.NumberOfGridPoints(2);
|
|
||||||
Params.Nz = this.NumberOfGridPoints(3);
|
|
||||||
|
|
||||||
% Dimensions (in units of l0)
|
|
||||||
Params.Lx = this.Dimensions(1);
|
|
||||||
Params.Ly = this.Dimensions(2);
|
|
||||||
Params.Lz = this.Dimensions(3);
|
|
||||||
|
|
||||||
% Trapping frequencies
|
|
||||||
Params.wx = 2*pi*this.TrapFrequencies(1);
|
|
||||||
Params.wy = 2*pi*this.TrapFrequencies(2);
|
|
||||||
Params.wz = 2*pi*this.TrapFrequencies(3);
|
|
||||||
|
|
||||||
% Trap depth and box size for box potentials
|
|
||||||
Params.boxdepth = this.TrapDepth/(Params.wz/w0); % The depth of the box
|
|
||||||
Params.boxsize = this.BoxSize; % The size of the box
|
|
||||||
|
|
||||||
% ================ Parameters defined by those above ================ %
|
|
||||||
|
|
||||||
% Trap gamma
|
|
||||||
Params.gx = (Params.wx/w0)^2;
|
|
||||||
Params.gy = (Params.wy/w0)^2;
|
|
||||||
Params.gz = (Params.wz/w0)^2;
|
|
||||||
|
|
||||||
end
|
|
@ -1,38 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
########### Begin SLURM header ###########
|
|
||||||
#Partition
|
|
||||||
#SBATCH --partition=single
|
|
||||||
# Request number of nodes and CPU cores per node for job
|
|
||||||
#SBATCH --nodes=1
|
|
||||||
#SBATCH --ntasks-per-node=1
|
|
||||||
#SBATCH --cpus-per-task=10
|
|
||||||
#SBATCH --mem=8G
|
|
||||||
# Estimated wallclock time for job
|
|
||||||
#SBATCH --time=02:00:00
|
|
||||||
#SBATCH --job-name=simulation
|
|
||||||
#SBATCH --error=simulation.err
|
|
||||||
#SBATCH --output=simulation.out
|
|
||||||
|
|
||||||
########### End SLURM header ##########
|
|
||||||
|
|
||||||
echo "Working Directory: $PWD"
|
|
||||||
echo "Running on host $HOSTNAME"
|
|
||||||
echo "Job id: $SLURM_JOB_ID"
|
|
||||||
echo "Job name: $SLURM_JOB_NAME"
|
|
||||||
echo "Number of nodes allocated to job: $SLURM_JOB_NUM_NODES"
|
|
||||||
echo "Number of cores allocated to job: $SLURM_JOB_CPUS_PER_NODE"
|
|
||||||
|
|
||||||
|
|
||||||
# Load module
|
|
||||||
module load math/matlab/R2023a
|
|
||||||
|
|
||||||
echo Directory is `pwd`
|
|
||||||
echo "Initiating Job..."
|
|
||||||
|
|
||||||
# Start a Matlab program
|
|
||||||
matlab -nodisplay -nosplash -r "Scripts.run_on_cluster"
|
|
||||||
|
|
||||||
# notice for tests
|
|
||||||
echo "Job terminated successfully"
|
|
||||||
|
|
||||||
exit
|
|
@ -1,233 +0,0 @@
|
|||||||
"""
|
|
||||||
@author: Adam Newton Wright, https://github.com/adamnewtonwright/GaussianBeamPropagation
|
|
||||||
"""
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
import sympy as sym
|
|
||||||
from sympy import oo
|
|
||||||
|
|
||||||
|
|
||||||
# Input Ray parameter, i.e. height and angle
|
|
||||||
def ray(y,theta):
|
|
||||||
'''
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
y : float or integer or sympy symbol in meters
|
|
||||||
The vertical height of a ray.
|
|
||||||
theta : float or integer in radians
|
|
||||||
The angle of divergence of the ray.
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
mat : 2x1 matrix
|
|
||||||
[
|
|
||||||
[y],
|
|
||||||
[teta]
|
|
||||||
]
|
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
mat = np.array([[y],[theta]])
|
|
||||||
return mat
|
|
||||||
|
|
||||||
# Ray Transfer Matrix for ideal lens with focal length f
|
|
||||||
def lens(f):
|
|
||||||
'''
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
f : float or integer or sympy symbol in meters
|
|
||||||
Thin lens focal length in meters
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
mat : 2x2 matrix
|
|
||||||
[
|
|
||||||
[ 1, 0],
|
|
||||||
[-1/f, 1]
|
|
||||||
]
|
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
mat = np.array([[1,0], [-1/f, 1]])
|
|
||||||
return mat
|
|
||||||
|
|
||||||
# Ray Transfer Matrix for propagation of distance d
|
|
||||||
def prop(d):
|
|
||||||
'''
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
d : float or integer or sympy symbol
|
|
||||||
Distance light is propagating along the z-axis.
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
mat: 2x2 matrix
|
|
||||||
[
|
|
||||||
[1, d],
|
|
||||||
[0, 1]
|
|
||||||
]
|
|
||||||
|
|
||||||
'''
|
|
||||||
mat = np.array([[1,d], [0,1]])
|
|
||||||
return mat
|
|
||||||
|
|
||||||
# multiplying the matrices together. mat1 is the last matrix the light interacts with
|
|
||||||
def mult(mat1,*argv):
|
|
||||||
'''
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
mat1 : 2x2 ABCD matrix
|
|
||||||
Last matrix light interacts with.
|
|
||||||
*argv : 2x2 ABCD matrices
|
|
||||||
From left to right, the matrices should be entered such that the leftmost matrix interacts
|
|
||||||
with light temporally after the rightmost matrix.
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
Mat : 2x2 matrix
|
|
||||||
The ABCd matrix describing the whole optical system.
|
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
Mat = mat1
|
|
||||||
for arg in argv:
|
|
||||||
Mat = np.dot(Mat, arg)
|
|
||||||
return Mat
|
|
||||||
|
|
||||||
# Adding Gaussian beam parameters
|
|
||||||
def Zr(wo, lam):
|
|
||||||
'''
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
wo : float, integer, or symbol
|
|
||||||
Beam waist radius in meters.
|
|
||||||
lam : float, integer, or symbol
|
|
||||||
Wavelength of light in meters.
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
zr : float, int, symbols
|
|
||||||
Rayleigh range for given beam waist and wavelength.
|
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
zr = np.pi * wo**2 / lam
|
|
||||||
return zr
|
|
||||||
|
|
||||||
def W0(zr, lam):
|
|
||||||
'''
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
zr : float, integer, symbol
|
|
||||||
Rayleigh range in meters
|
|
||||||
lam : float, integer, symbol
|
|
||||||
Wavelength of light in meters
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
w0 : float, integer, symbol
|
|
||||||
Beam waist radius in meters
|
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
w0 = np.sqrt(lam * zr / np.pi)
|
|
||||||
return w0
|
|
||||||
|
|
||||||
# Remember, there should be an i in front of zr
|
|
||||||
# but this complicates the calculations, so we usually just let z = 0
|
|
||||||
# and don't explicitly deal with the i, but still do the math accordingly
|
|
||||||
#def q0_func(z,zr):
|
|
||||||
# qz = z + zr
|
|
||||||
# return qz
|
|
||||||
|
|
||||||
def q1_func(z, w0, lam, mat):
|
|
||||||
'''
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
z : float, int, symbol
|
|
||||||
Position of the beam waist in meters.
|
|
||||||
w0 : float, int, symbol
|
|
||||||
Radial waist size in meters (of the embedded Gaussian, i.e. W0/M).
|
|
||||||
lam : float, int, symbol
|
|
||||||
Wavelength of light in meters.
|
|
||||||
mat : float, int, symbol
|
|
||||||
The ABCD 2x2 matrix describing the optical system.
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
z: float, int, symbol
|
|
||||||
Position of the beam waist after the optical system
|
|
||||||
zr: float, int, symbol
|
|
||||||
Rayleigh range of the beam after the optical system
|
|
||||||
'''
|
|
||||||
|
|
||||||
A = mat[0][0]
|
|
||||||
B = mat[0][1]
|
|
||||||
C = mat[1][0]
|
|
||||||
D = mat[1][1]
|
|
||||||
zr = Zr(w0, lam)
|
|
||||||
real = (A*C*(z**2 + zr**2) + z*(A*D + B*C) + B*D) / (C**2*(z**2 + zr**2) + 2*C*D*z + D**2)
|
|
||||||
imag = (zr * (A*D - B*C)) / (C**2*(z**2 + zr**2) + 2*C*D*z + D**2)
|
|
||||||
z = real
|
|
||||||
zr = imag
|
|
||||||
return z, zr
|
|
||||||
|
|
||||||
def q1_inv_func(z, w0, lam, mat):
|
|
||||||
'''
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
z : float, int, symbol
|
|
||||||
Position of the beam waist in meters.
|
|
||||||
w0 : float, int, symbol
|
|
||||||
Radial waist size in meters (of the embedded Gaussian, i.e. W0/M).
|
|
||||||
lam : float, int, symbol
|
|
||||||
Wavelength of light in meters.
|
|
||||||
mat : float, int, symbol
|
|
||||||
The ABCD 2x2 matrix describing the optical system.
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
R : float, int, symbol
|
|
||||||
Radius of curvature of the wavefront in meters.
|
|
||||||
w : float, int, symbol
|
|
||||||
Radius of the beam in meters.
|
|
||||||
|
|
||||||
'''
|
|
||||||
A = mat[0][0]
|
|
||||||
B = mat[0][1]
|
|
||||||
C = mat[1,0]
|
|
||||||
D = mat[1][1]
|
|
||||||
zr = Zr(w0, lam)
|
|
||||||
real = (A*C*(z**2 + zr**2) + z*(A*D + B*C) + B*D) / (A**2*(z**2 + zr**2) + 2*A*B*z + B**2)
|
|
||||||
imag = -zr * (A*D-B*C) / (A**2 *(z**2 + zr**2) + 2*A*B*z + B**2)
|
|
||||||
R = 1/real
|
|
||||||
w = (-lam / imag / np.pi)**.5
|
|
||||||
return R, w
|
|
||||||
|
|
||||||
def plot(func, var, rang = np.arange(0,3,.01)):
|
|
||||||
'''
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
func : Sympy function of one variable
|
|
||||||
Sympy function defining the beam width after the last optical element.
|
|
||||||
var : sympy variable
|
|
||||||
Variable in func that will be plotted.
|
|
||||||
rang : numpy array
|
|
||||||
Array of the values along the optical axis to be plotted
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
plot : matplotlib graph
|
|
||||||
Graph of the beam width of var
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
func = sym.lambdify(var, func)
|
|
||||||
plt.figure()
|
|
||||||
plt.plot(rang, func(rang), color = 'b')
|
|
||||||
plt.plot(rang, -func(rang), color = 'b')
|
|
||||||
plt.grid()
|
|
||||||
plt.xlabel('Optic Axis (m)')
|
|
||||||
plt.ylabel('Beam size (m)')
|
|
||||||
plt.show()
|
|
File diff suppressed because one or more lines are too long
@ -1,70 +0,0 @@
|
|||||||
import BeamPropagation as bp # This is the script that handles the propagation
|
|
||||||
import sympy as sym # For Symbolic examples
|
|
||||||
import numpy as np # Handling of lists and for plotting
|
|
||||||
import matplotlib.pyplot as plt # Plotting
|
|
||||||
|
|
||||||
|
|
||||||
"""A Gaussian beam can be defined by it's (radial) waist wo, it's Rayleigh range zR, and the location of its waist zO"""
|
|
||||||
w0 = 5.2E-3 # 1mm beam waist
|
|
||||||
lam = 532E-9 # wavelength of 355 nm (UV)
|
|
||||||
zR = bp.Zr(w0, lam) # Rayleigh range in m
|
|
||||||
z0 = 0 # location of waist in m
|
|
||||||
|
|
||||||
"""Define first 4-f optical system using matrices"""
|
|
||||||
d1, d2, d3, f1, f2 = sym.symbols('d1 d2 d3 f1 f2')
|
|
||||||
M = bp.mult(bp.prop(d3),bp.lens(f2),bp.prop(d2), bp.lens(f1), bp.prop(d1))
|
|
||||||
|
|
||||||
"""Use script to do all the ABCD and q-parameter math, and return the waist and radius of curvature functions"""
|
|
||||||
R, w = bp.q1_inv_func(0, w0, lam, M)
|
|
||||||
|
|
||||||
"""Substitute and extract the required separation between lenses of first 4-f system"""
|
|
||||||
distance_between_dmd_first_lens = 250E-3
|
|
||||||
first_focal_length = 250.9E-3
|
|
||||||
second_focal_length = 50E-3
|
|
||||||
demag = 1/5
|
|
||||||
target_w0 = demag*w0
|
|
||||||
w = w.subs(f1, first_focal_length).subs(f2, second_focal_length).subs(d1, distance_between_dmd_first_lens).subs(d3,0)
|
|
||||||
eq = sym.solve(w - target_w0, d2)[0]
|
|
||||||
distance_between_lens_of_first_4f = list(eq.atoms())[0]
|
|
||||||
print('Distance between lenses of first 4-f system = {} mm'.format(distance_between_lens_of_first_4f * 1E3))
|
|
||||||
|
|
||||||
# Sanity check
|
|
||||||
# expansion_factor = w.subs(d2,distance_between_lens_of_first_4f).subs(d3,0)/ w0
|
|
||||||
# print('beam is w = {:.2f} x w0'.format(expansion_factor))
|
|
||||||
|
|
||||||
# """Plot beam propagation up to 3 m after the first 4-f system"""
|
|
||||||
# M = bp.mult(bp.prop(d3),bp.lens(second_focal_length),bp.prop(distance_between_lens_of_first_4f), bp.lens(first_focal_length), bp.prop(distance_between_dmd_first_lens))
|
|
||||||
# R, w = bp.q1_inv_func(0, w0, lam, M)
|
|
||||||
# bp.plot(w,d3, rang = np.arange(0,0.050,.0005))
|
|
||||||
|
|
||||||
|
|
||||||
"""Define the full optical system of two 4-f setups using matrices"""
|
|
||||||
d1, d2, d3, d4, f1, f2, f3 = sym.symbols('d1 d2 d3 d4 f1 f2 f3')
|
|
||||||
M = bp.mult(bp.prop(d4),bp.lens(f3), bp.prop(d3),bp.lens(f2),bp.prop(d2), bp.lens(f1), bp.prop(d1))
|
|
||||||
|
|
||||||
"""Use script to do all the ABCD and q-parameter math, and return the waist and radius of curvature functions"""
|
|
||||||
R, w = bp.q1_inv_func(0, w0, lam, M)
|
|
||||||
|
|
||||||
# """Find the focal length of lens required after the first 4-f system to have a collimated beam, given a certain separation between the first 4-f system and this lens"""
|
|
||||||
distance_between_4fs = 550E-3
|
|
||||||
R_coll = R.subs(d1,distance_between_dmd_first_lens).subs(d2,distance_between_lens_of_first_4f).subs(d3,distance_between_4fs).subs(d4,0).subs(f1,first_focal_length).subs(f2,second_focal_length)
|
|
||||||
f3_coll = sym.solve(1/R_coll,f3)[0]
|
|
||||||
third_focal_length = list(f3_coll.atoms())[0]
|
|
||||||
print('For a fixed separation between first 4-f and third lens of {:.3f} mm, f3 = {:.3f} mm for a collimated beam'.format(distance_between_4fs* 1E3, third_focal_length * 1E3))
|
|
||||||
|
|
||||||
# # """Plot beam propagation up to 3 m after the first 4-f system"""
|
|
||||||
# M = bp.mult(bp.prop(d4),bp.lens(third_focal_length),bp.prop(distance_between_4fs), bp.lens(second_focal_length), bp.prop(distance_between_lens_of_first_4f), bp.lens(first_focal_length), bp.prop(distance_between_dmd_first_lens))
|
|
||||||
# R, w = bp.q1_inv_func(0, w0, lam, M)
|
|
||||||
# bp.plot(w,d4, rang = np.arange(0,0.050,.0005))
|
|
||||||
|
|
||||||
third_focal_length = 501.8E-3
|
|
||||||
R_coll = R.subs(d1,distance_between_dmd_first_lens).subs(d2,distance_between_lens_of_first_4f).subs(d4,0).subs(f1,first_focal_length).subs(f2,second_focal_length).subs(f3,third_focal_length)
|
|
||||||
d3_coll = sym.solve(1/R_coll,d3)[1]
|
|
||||||
distance_between_4fs = list(d3_coll.atoms())[0]
|
|
||||||
print('For a fixed third focal length of {:.3f} mm, d3 = {:.3f} mm, for a collimated beam'.format(third_focal_length* 1E3, distance_between_4fs * 1E3))
|
|
||||||
|
|
||||||
# """Plot beam propagation up to 3 m after the first 4-f system"""
|
|
||||||
# M = bp.mult(bp.prop(d4),bp.lens(third_focal_length),bp.prop(distance_between_4fs), bp.lens(second_focal_length), bp.prop(distance_between_lens_of_first_4f), bp.lens(first_focal_length), bp.prop(distance_between_dmd_first_lens))
|
|
||||||
# R, w = bp.q1_inv_func(0, w0, lam, M)
|
|
||||||
# bp.plot(w,d4, rang = np.arange(0,0.050,.0005))
|
|
||||||
|
|
@ -1,469 +0,0 @@
|
|||||||
%% Parameters
|
|
||||||
|
|
||||||
groupList = ["/images/MOT_3D_Camera/in_situ_absorption", "/images/ODT_1_Axis_Camera/in_situ_absorption", "/images/ODT_2_Axis_Camera/in_situ_absorption", "/images/Horizontal_Axis_Camera/in_situ_absorption", "/images/Vertical_Axis_Camera/in_situ_absorption"];
|
|
||||||
|
|
||||||
folderPath = "C:/Users/Karthik/Documents/GitRepositories/Calculations/IRF/0044/";
|
|
||||||
|
|
||||||
cam = 5;
|
|
||||||
|
|
||||||
angle = 90 + 51.5;
|
|
||||||
center = [1700, 2300];
|
|
||||||
span = [255, 255];
|
|
||||||
fraction = [0.1, 0.1];
|
|
||||||
|
|
||||||
NA = 0.6;
|
|
||||||
pixel_size = 4.6e-6;
|
|
||||||
lambda = 421e-9;
|
|
||||||
|
|
||||||
d = lambda/2/pi/NA;
|
|
||||||
k_cutoff = NA/lambda/1e6;
|
|
||||||
|
|
||||||
%% Compute OD image, rotate and extract ROI for analysis
|
|
||||||
% Get a list of all files in the folder with the desired file name pattern.
|
|
||||||
filePattern = fullfile(folderPath, '*.h5');
|
|
||||||
files = dir(filePattern);
|
|
||||||
refimages = zeros(span(1) + 1, span(2) + 1, length(files));
|
|
||||||
absimages = zeros(span(1) + 1, span(2) + 1, length(files));
|
|
||||||
|
|
||||||
|
|
||||||
for k = 1 : length(files)
|
|
||||||
baseFileName = files(k).name;
|
|
||||||
fullFileName = fullfile(files(k).folder, baseFileName);
|
|
||||||
|
|
||||||
fprintf(1, 'Now reading %s\n', fullFileName);
|
|
||||||
|
|
||||||
atm_img = im2double(imrotate(h5read(fullFileName, append(groupList(cam), "/atoms")), angle));
|
|
||||||
bkg_img = im2double(imrotate(h5read(fullFileName, append(groupList(cam), "/background")), angle));
|
|
||||||
dark_img = im2double(imrotate(h5read(fullFileName, append(groupList(cam), "/dark")), angle));
|
|
||||||
|
|
||||||
refimages(:,:,k) = subtract_offset(crop_image(bkg_img, center, span), fraction);
|
|
||||||
absimages(:,:,k) = subtract_offset(crop_image(calculate_OD(atm_img, bkg_img, dark_img), center, span), fraction);
|
|
||||||
|
|
||||||
end
|
|
||||||
%% Fringe removal
|
|
||||||
|
|
||||||
optrefimages = removefringesInImage(absimages, refimages);
|
|
||||||
absimages_fringe_removed = absimages(:, :, :) - optrefimages(:, :, :);
|
|
||||||
|
|
||||||
nimgs = size(absimages_fringe_removed,3);
|
|
||||||
od_imgs = cell(1, nimgs);
|
|
||||||
for i = 1:nimgs
|
|
||||||
od_imgs{i} = absimages_fringe_removed(:, :, i);
|
|
||||||
end
|
|
||||||
|
|
||||||
%% Compute the Density Noise Spectrum
|
|
||||||
|
|
||||||
mean_subtracted_od_imgs = cell(1, length(od_imgs));
|
|
||||||
mean_od_img = mean(cat(3, od_imgs{:}), 3, 'double');
|
|
||||||
|
|
||||||
density_fft = cell(1, length(od_imgs));
|
|
||||||
density_noise_spectrum = cell(1, length(od_imgs));
|
|
||||||
|
|
||||||
[Nx, Ny] = size(mean_od_img);
|
|
||||||
dx = pixel_size;
|
|
||||||
dy = pixel_size;
|
|
||||||
|
|
||||||
xvals = (1:Nx)*dx*1e6;
|
|
||||||
yvals = (1:Ny)*dy*1e6;
|
|
||||||
|
|
||||||
Nyq_k = 1/dx; % Nyquist
|
|
||||||
dk = 1/(Nx*dx); % Wavenumber increment
|
|
||||||
kx = -Nyq_k/2:dk:Nyq_k/2-dk; % wavenumber
|
|
||||||
kx = kx * dx; % wavenumber (in units of 1/dx)
|
|
||||||
|
|
||||||
Nyq_k = 1/dy; % Nyquist
|
|
||||||
dk = 1/(Ny*dy); % Wavenumber increment
|
|
||||||
ky = -Nyq_k/2:dk:Nyq_k/2-dk; % wavenumber
|
|
||||||
ky = ky * dy; % wavenumber (in units of 1/dy)
|
|
||||||
|
|
||||||
% Create Circular Mask
|
|
||||||
n = 2^8; % size of mask
|
|
||||||
mask = zeros(n);
|
|
||||||
I = 1:n;
|
|
||||||
x = I-n/2; % mask x-coordinates
|
|
||||||
y = n/2-I; % mask y-coordinates
|
|
||||||
[X,Y] = meshgrid(x,y); % create 2-D mask grid
|
|
||||||
R = 32; % aperture radius
|
|
||||||
A = (X.^2 + Y.^2 <= R^2); % circular aperture of radius R
|
|
||||||
mask(A) = 1; % set mask elements inside aperture to 1
|
|
||||||
|
|
||||||
|
|
||||||
% Calculate Power Spectrum and plot
|
|
||||||
figure('Position', [100, 100, 1200, 800]);
|
|
||||||
clf
|
|
||||||
|
|
||||||
for k = 1 : length(od_imgs)
|
|
||||||
mean_subtracted_od_imgs{k} = od_imgs{k} - mean_od_img;
|
|
||||||
masked_img = mean_subtracted_od_imgs{k} .* mask;
|
|
||||||
density_fft{k} = (1/numel(masked_img)) * abs(fftshift(fft2(masked_img)));
|
|
||||||
density_noise_spectrum{k} = density_fft{k}.^2;
|
|
||||||
|
|
||||||
% Subplot 1
|
|
||||||
% subplot(2, 3, 1);
|
|
||||||
subplot('Position', [0.05, 0.55, 0.28, 0.4])
|
|
||||||
imagesc(xvals, yvals, od_imgs{k})
|
|
||||||
xlabel('µm', 'FontSize', 16)
|
|
||||||
ylabel('µm', 'FontSize', 16)
|
|
||||||
axis equal tight;
|
|
||||||
colorbar
|
|
||||||
colormap (flip(jet));
|
|
||||||
% set(gca,'CLim',[0 100]);
|
|
||||||
set(gca,'YDir','normal')
|
|
||||||
title('Single-shot image', 'FontSize', 16);
|
|
||||||
|
|
||||||
% Subplot 2
|
|
||||||
% subplot(2, 3, 2);
|
|
||||||
subplot('Position', [0.36, 0.55, 0.28, 0.4])
|
|
||||||
imagesc(xvals, yvals, mean_od_img)
|
|
||||||
xlabel('µm', 'FontSize', 16)
|
|
||||||
ylabel('µm', 'FontSize', 16)
|
|
||||||
axis equal tight;
|
|
||||||
colorbar
|
|
||||||
colormap (flip(jet));
|
|
||||||
% set(gca,'CLim',[0 100]);
|
|
||||||
set(gca,'YDir','normal')
|
|
||||||
title('Averaged density image', 'FontSize', 16);
|
|
||||||
|
|
||||||
% Subplot 3
|
|
||||||
% subplot(2, 3, 3);
|
|
||||||
subplot('Position', [0.67, 0.55, 0.28, 0.4]);
|
|
||||||
imagesc(xvals, yvals, mean_subtracted_od_imgs{k})
|
|
||||||
xlabel('µm', 'FontSize', 16)
|
|
||||||
ylabel('µm', 'FontSize', 16)
|
|
||||||
axis equal tight;
|
|
||||||
colorbar
|
|
||||||
colormap (flip(jet));
|
|
||||||
% set(gca,'CLim',[0 100]);
|
|
||||||
set(gca,'YDir','normal')
|
|
||||||
title('Image noise = Single-shot - Average', 'FontSize', 16);
|
|
||||||
|
|
||||||
% Subplot 4
|
|
||||||
% subplot(2, 3, 4);
|
|
||||||
subplot('Position', [0.05, 0.05, 0.28, 0.4]);
|
|
||||||
imagesc(xvals, yvals, mean_subtracted_od_imgs{k} .* mask)
|
|
||||||
xlabel('µm', 'FontSize', 16)
|
|
||||||
ylabel('µm', 'FontSize', 16)
|
|
||||||
axis equal tight;
|
|
||||||
colorbar
|
|
||||||
colormap (flip(jet));
|
|
||||||
% set(gca,'CLim',[0 100]);
|
|
||||||
set(gca,'YDir','normal')
|
|
||||||
title('Masked Noise', 'FontSize', 16);
|
|
||||||
|
|
||||||
% Subplot 5
|
|
||||||
% subplot(2, 3, 5);
|
|
||||||
subplot('Position', [0.36, 0.05, 0.28, 0.4]);
|
|
||||||
imagesc(kx, ky, abs(log2(density_fft{k})))
|
|
||||||
xlabel('1/dx', 'FontSize', 16)
|
|
||||||
ylabel('1/dy', 'FontSize', 16)
|
|
||||||
axis equal tight;
|
|
||||||
colorbar
|
|
||||||
colormap (flip(jet));
|
|
||||||
% set(gca,'CLim',[0 100]);
|
|
||||||
set(gca,'YDir','normal')
|
|
||||||
title('DFT', 'FontSize', 16);
|
|
||||||
|
|
||||||
% Subplot 6
|
|
||||||
% subplot(2, 3, 6);
|
|
||||||
subplot('Position', [0.67, 0.05, 0.28, 0.4]);
|
|
||||||
imagesc(kx, ky, abs(log2(density_noise_spectrum{k})))
|
|
||||||
xlabel('1/dx', 'FontSize', 16)
|
|
||||||
ylabel('1/dy', 'FontSize', 16)
|
|
||||||
axis equal tight;
|
|
||||||
colorbar
|
|
||||||
colormap (flip(jet));
|
|
||||||
% set(gca,'CLim',[0 100]);
|
|
||||||
set(gca,'YDir','normal')
|
|
||||||
title('Density Noise Spectrum = |DFT|^2', 'FontSize', 16);
|
|
||||||
|
|
||||||
drawnow;
|
|
||||||
end
|
|
||||||
|
|
||||||
%% Compute the average 2D spectrum and do radial averaging to get the 1D spectrum
|
|
||||||
|
|
||||||
% Compute the average power spectrum.
|
|
||||||
averagePowerSpectrum = mean(cat(3, density_noise_spectrum{:}), 3, 'double');
|
|
||||||
|
|
||||||
% Plot the average power spectrum.
|
|
||||||
figure('Position', [100, 100, 1200, 500]);
|
|
||||||
clf
|
|
||||||
|
|
||||||
subplot('Position', [0.05, 0.1, 0.4, 0.8]) % Adjusted position
|
|
||||||
imagesc(abs(10*log10(averagePowerSpectrum)))
|
|
||||||
axis equal tight;
|
|
||||||
colorbar
|
|
||||||
colormap(flip(jet));
|
|
||||||
% set(gca,'CLim',[0 1e-7]);
|
|
||||||
title('Average Density Noise Spectrum', 'FontSize', 16);
|
|
||||||
grid on;
|
|
||||||
centers = ginput;
|
|
||||||
radius = 6;
|
|
||||||
% Plot where clicked.
|
|
||||||
hVC = viscircles(centers, radius, 'Color', 'r', 'LineWidth', 2);
|
|
||||||
xc = centers(:,1);
|
|
||||||
% xc = [78.2600, 108.3400, 128.8200, 150.5800, 181.3000];
|
|
||||||
yc = centers(:,2);
|
|
||||||
% yc = [131.3800, 155.7000, 128.8200, 101.3000, 126.2600];
|
|
||||||
[yDim, xDim] = size(averagePowerSpectrum);
|
|
||||||
[xx,yy] = meshgrid(1:yDim,1:xDim);
|
|
||||||
mask = false(xDim,yDim);
|
|
||||||
for ii = 1:length(centers)
|
|
||||||
mask = mask | hypot(xx - xc(ii), yy - yc(ii)) <= radius;
|
|
||||||
end
|
|
||||||
mask = not(mask);
|
|
||||||
|
|
||||||
x1 = 1;
|
|
||||||
y1 = 1;
|
|
||||||
x2 = 256;
|
|
||||||
y2 = 256;
|
|
||||||
|
|
||||||
% Ask user if the circle is acceptable.
|
|
||||||
message = sprintf('Is this acceptable?');
|
|
||||||
button = questdlg(message, message, 'Accept', 'Reject and Quit', 'Accept');
|
|
||||||
if contains(button, 'Accept','IgnoreCase',true)
|
|
||||||
image = mask.*averagePowerSpectrum;
|
|
||||||
image(image==0) = NaN;
|
|
||||||
imagesc(kx, ky, mask.*abs(10*log10(averagePowerSpectrum)))
|
|
||||||
hold on
|
|
||||||
line([kx(x1),kx(x2)], [ky(y1),ky(y2)], 'Color','white', 'LineStyle','--', 'LineWidth', 4);
|
|
||||||
% imagesc(kx, ky, 10*log10(averagePowerSpectrum))
|
|
||||||
% imagesc(kx, ky, log2(averagePowerSpectrum))
|
|
||||||
% imagesc(kx, ky, averagePowerSpectrum)
|
|
||||||
xlabel('1/dx', 'FontSize', 16)
|
|
||||||
ylabel('1/dy', 'FontSize', 16)
|
|
||||||
axis equal tight;
|
|
||||||
colorbar
|
|
||||||
colormap(flip(jet));
|
|
||||||
% set(gca,'CLim',[0 1e-7]);
|
|
||||||
title('Average Density Noise Spectrum', 'FontSize', 16);
|
|
||||||
grid on;
|
|
||||||
elseif contains(button, 'Quit','IgnoreCase',true)
|
|
||||||
delete(hVC); % Delete the circle from the overlay.
|
|
||||||
image = averagePowerSpectrum;
|
|
||||||
imagesc(kx, ky, abs(10*log10(averagePowerSpectrum)))
|
|
||||||
% imagesc(kx, ky, 10*log10(averagePowerSpectrum))
|
|
||||||
% imagesc(kx, ky, log2(averagePowerSpectrum))
|
|
||||||
% imagesc(kx, ky, averagePowerSpectrum)
|
|
||||||
xlabel('1/dx', 'FontSize', 16)
|
|
||||||
ylabel('1/dy', 'FontSize', 16)
|
|
||||||
axis equal tight;
|
|
||||||
colorbar
|
|
||||||
colormap(flip(jet));
|
|
||||||
% set(gca,'CLim',[0 1e-7]);
|
|
||||||
title('Average Density Noise Spectrum', 'FontSize', 16);
|
|
||||||
grid on;
|
|
||||||
end
|
|
||||||
|
|
||||||
subplot('Position', [0.55, 0.1, 0.4, 0.8]) % Adjusted position
|
|
||||||
% [r, Zr] = radial_profile(averagePowerSpectrum, 1);
|
|
||||||
% Zr = (Zr - min(Zr))./(max(Zr) - min(Zr));
|
|
||||||
% plot(r, Zr, 'o-', 'MarkerSize', 4, 'MarkerFaceColor', 'none');
|
|
||||||
% set(gca, 'XScale', 'log'); % Setting x-axis to log scale
|
|
||||||
|
|
||||||
[xi, yi, profile] = improfile(image, [x1,x2], [y1,y2]);
|
|
||||||
profile = (profile - min(profile))./(max(profile) - min(profile));
|
|
||||||
ks = sqrt(kx.^2 + ky.^2);
|
|
||||||
|
|
||||||
profile = profile(length(profile)/2:end);
|
|
||||||
ks = ks(length(ks)/2:end);
|
|
||||||
|
|
||||||
n = 0.15;
|
|
||||||
[val,slice_idx]=min(abs(ks-n));
|
|
||||||
ks = ks(1:slice_idx);
|
|
||||||
profile = profile(1:slice_idx);
|
|
||||||
plot(ks, profile, 'b*-');
|
|
||||||
% plot(profile, 'b*-');
|
|
||||||
grid on;
|
|
||||||
% xlim([min(ks) max(ks)])
|
|
||||||
title('Radial average of Density Noise Spectrum', 'FontSize', 16);
|
|
||||||
grid on;
|
|
||||||
|
|
||||||
|
|
||||||
%% Helper Functions
|
|
||||||
|
|
||||||
function ret = get_offset_from_corner(img, x_fraction, y_fraction)
|
|
||||||
% image must be a 2D numerical array
|
|
||||||
[dim1, dim2] = size(img);
|
|
||||||
|
|
||||||
s1 = img(1:round(dim1 * y_fraction), 1:round(dim2 * x_fraction));
|
|
||||||
s2 = img(1:round(dim1 * y_fraction), round(dim2 - dim2 * x_fraction):dim2);
|
|
||||||
s3 = img(round(dim1 - dim1 * y_fraction):dim1, 1:round(dim2 * x_fraction));
|
|
||||||
s4 = img(round(dim1 - dim1 * y_fraction):dim1, round(dim2 - dim2 * x_fraction):dim2);
|
|
||||||
|
|
||||||
ret = mean([mean(s1(:)), mean(s2(:)), mean(s3(:)), mean(s4(:))]);
|
|
||||||
end
|
|
||||||
|
|
||||||
function ret = subtract_offset(img, fraction)
|
|
||||||
% Remove the background from the image.
|
|
||||||
% :param dataArray: The image
|
|
||||||
% :type dataArray: xarray DataArray
|
|
||||||
% :param x_fraction: The fraction of the pixels used in x axis
|
|
||||||
% :type x_fraction: float
|
|
||||||
% :param y_fraction: The fraction of the pixels used in y axis
|
|
||||||
% :type y_fraction: float
|
|
||||||
% :return: The image after removing background
|
|
||||||
% :rtype: xarray DataArray
|
|
||||||
|
|
||||||
x_fraction = fraction(1);
|
|
||||||
y_fraction = fraction(2);
|
|
||||||
offset = get_offset_from_corner(img, x_fraction, y_fraction);
|
|
||||||
ret = img - offset;
|
|
||||||
end
|
|
||||||
|
|
||||||
function ret = crop_image(img, center, span)
|
|
||||||
% Crop the image according to the region of interest (ROI).
|
|
||||||
% :param dataSet: The images
|
|
||||||
% :type dataSet: xarray DataArray or DataSet
|
|
||||||
% :param center: The center of region of interest (ROI)
|
|
||||||
% :type center: tuple
|
|
||||||
% :param span: The span of region of interest (ROI)
|
|
||||||
% :type span: tuple
|
|
||||||
% :return: The cropped images
|
|
||||||
% :rtype: xarray DataArray or DataSet
|
|
||||||
|
|
||||||
x_start = floor(center(1) - span(1) / 2);
|
|
||||||
x_end = floor(center(1) + span(1) / 2);
|
|
||||||
y_start = floor(center(2) - span(2) / 2);
|
|
||||||
y_end = floor(center(2) + span(2) / 2);
|
|
||||||
|
|
||||||
ret = img(y_start:y_end, x_start:x_end);
|
|
||||||
end
|
|
||||||
|
|
||||||
function ret = calculate_OD(imageAtom, imageBackground, imageDark)
|
|
||||||
% Calculate the OD image for absorption imaging.
|
|
||||||
% :param imageAtom: The image with atoms
|
|
||||||
% :type imageAtom: numpy array
|
|
||||||
% :param imageBackground: The image without atoms
|
|
||||||
% :type imageBackground: numpy array
|
|
||||||
% :param imageDark: The image without light
|
|
||||||
% :type imageDark: numpy array
|
|
||||||
% :return: The OD images
|
|
||||||
% :rtype: numpy array
|
|
||||||
|
|
||||||
numerator = imageBackground - imageDark;
|
|
||||||
denominator = imageAtom - imageDark;
|
|
||||||
|
|
||||||
numerator(numerator == 0) = 1;
|
|
||||||
denominator(denominator == 0) = 1;
|
|
||||||
|
|
||||||
ret = -log(double(abs(denominator ./ numerator)));
|
|
||||||
|
|
||||||
if numel(ret) == 1
|
|
||||||
ret = ret(1);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function [R, Zr] = radial_profile(data,radial_step)
|
|
||||||
x = (1:size(data,2))-size(data,2)/2;
|
|
||||||
y = (1:size(data,1))-size(data,1)/2;
|
|
||||||
% coordinate grid:
|
|
||||||
[X,Y] = meshgrid(x,y);
|
|
||||||
% creating circular layers
|
|
||||||
Z_integer = round(abs(X+1i*Y)/radial_step)+1;
|
|
||||||
% very fast MatLab calculations:
|
|
||||||
R = accumarray(Z_integer(:),abs(X(:)+1i*Y(:)),[],@mean);
|
|
||||||
Zr = accumarray(Z_integer(:),data(:),[],@mean);
|
|
||||||
end
|
|
||||||
|
|
||||||
function [M] = ImagingResponseFunction(B)
|
|
||||||
x = -100:100;
|
|
||||||
y = x;
|
|
||||||
[X,Y] = meshgrid(x,y);
|
|
||||||
R = sqrt(X.^2+Y.^2);
|
|
||||||
PHI = atan2(X,Y)+pi;
|
|
||||||
%fit parameters
|
|
||||||
tau = B(1);
|
|
||||||
alpha = B(2);
|
|
||||||
S0 = B(3);
|
|
||||||
phi = B(4);
|
|
||||||
beta = B(5);
|
|
||||||
delta = B(6);
|
|
||||||
A = B(7);
|
|
||||||
C = B(8);
|
|
||||||
a = B(9);
|
|
||||||
U = heaviside(1-R/a).*exp(-R.^2/a^2/tau^2);
|
|
||||||
THETA = S0*(R/a).^4 + alpha*(R/a).^2.*cos(2*PHI-2*phi) + beta*(R/a).^2;
|
|
||||||
p = U.*exp(1i.*THETA);
|
|
||||||
M = A*abs((ifft2(real(exp(1i*delta).*fftshift(fft2(p)))))).^2 + C;
|
|
||||||
end
|
|
||||||
|
|
||||||
function [RadialResponseFunc] = RadialImagingResponseFunction(C, k, kmax)
|
|
||||||
A = heaviside(1-k/kmax).*exp(-C(1)*k.^4);
|
|
||||||
W = C(2) + C(3)*k.^2 + C(4)*k.^4;
|
|
||||||
RadialResponseFunc = 0;
|
|
||||||
for n = -30:30
|
|
||||||
RadialResponseFunc = RadialResponseFunc + besselj(n,C(5)*k.^2).^2 + besselj(n,C(5)*k.^2).*besselj(-n,C(5)*k.^2).*cos(2*W);
|
|
||||||
end
|
|
||||||
RadialResponseFunc = C(6)*1/2*A.*RadialResponseFunc;
|
|
||||||
end
|
|
||||||
|
|
||||||
function [optrefimages] = removefringesInImage(absimages, refimages, bgmask)
|
|
||||||
% removefringesInImage - Fringe removal and noise reduction from absorption images.
|
|
||||||
% Creates an optimal reference image for each absorption image in a set as
|
|
||||||
% a linear combination of reference images, with coefficients chosen to
|
|
||||||
% minimize the least-squares residuals between each absorption image and
|
|
||||||
% the optimal reference image. The coefficients are obtained by solving a
|
|
||||||
% linear set of equations using matrix inverse by LU decomposition.
|
|
||||||
%
|
|
||||||
% Application of the algorithm is described in C. F. Ockeloen et al, Improved
|
|
||||||
% detection of small atom numbers through image processing, arXiv:1007.2136 (2010).
|
|
||||||
%
|
|
||||||
% Syntax:
|
|
||||||
% [optrefimages] = removefringesInImage(absimages,refimages,bgmask);
|
|
||||||
%
|
|
||||||
% Required inputs:
|
|
||||||
% absimages - Absorption image data,
|
|
||||||
% typically 16 bit grayscale images
|
|
||||||
% refimages - Raw reference image data
|
|
||||||
% absimages and refimages are both cell arrays containing
|
|
||||||
% 2D array data. The number of refimages can differ from the
|
|
||||||
% number of absimages.
|
|
||||||
%
|
|
||||||
% Optional inputs:
|
|
||||||
% bgmask - Array specifying background region used,
|
|
||||||
% 1=background, 0=data. Defaults to all ones.
|
|
||||||
% Outputs:
|
|
||||||
% optrefimages - Cell array of optimal reference images,
|
|
||||||
% equal in size to absimages.
|
|
||||||
%
|
|
||||||
|
|
||||||
% Dependencies: none
|
|
||||||
%
|
|
||||||
% Authors: Shannon Whitlock, Caspar Ockeloen
|
|
||||||
% Reference: C. F. Ockeloen, A. F. Tauschinsky, R. J. C. Spreeuw, and
|
|
||||||
% S. Whitlock, Improved detection of small atom numbers through
|
|
||||||
% image processing, arXiv:1007.2136
|
|
||||||
% Email:
|
|
||||||
% May 2009; Last revision: 11 August 2010
|
|
||||||
|
|
||||||
% Process inputs
|
|
||||||
|
|
||||||
% Set variables, and flatten absorption and reference images
|
|
||||||
nimgs = size(absimages,3);
|
|
||||||
nimgsR = size(refimages,3);
|
|
||||||
xdim = size(absimages(:,:,1),2);
|
|
||||||
ydim = size(absimages(:,:,1),1);
|
|
||||||
|
|
||||||
R = single(reshape(refimages,xdim*ydim,nimgsR));
|
|
||||||
A = single(reshape(absimages,xdim*ydim,nimgs));
|
|
||||||
optrefimages=zeros(size(absimages)); % preallocate
|
|
||||||
|
|
||||||
if not(exist('bgmask','var')); bgmask=ones(ydim,xdim); end
|
|
||||||
k = find(bgmask(:)==1); % Index k specifying background region
|
|
||||||
|
|
||||||
% Ensure there are no duplicate reference images
|
|
||||||
% R=unique(R','rows')'; % comment this line if you run out of memory
|
|
||||||
|
|
||||||
% Decompose B = R*R' using singular value or LU decomposition
|
|
||||||
[L,U,p] = lu(R(k,:)'*R(k,:),'vector'); % LU decomposition
|
|
||||||
|
|
||||||
for j=1:nimgs
|
|
||||||
b=R(k,:)'*A(k,j);
|
|
||||||
% Obtain coefficients c which minimise least-square residuals
|
|
||||||
lower.LT = true; upper.UT = true;
|
|
||||||
c = linsolve(U,linsolve(L,b(p,:),lower),upper);
|
|
||||||
|
|
||||||
% Compute optimised reference image
|
|
||||||
optrefimages(:,:,j)=reshape(R*c,[ydim xdim]);
|
|
||||||
end
|
|
||||||
end
|
|
Binary file not shown.
@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* Based on code snippet from
|
|
||||||
* http://java.sun.com/developer/technicalArticles/releases/data/
|
|
||||||
*
|
|
||||||
* Copyright © 2008, 2010 Oracle and/or its affiliates. All rights reserved. Use is subject to license terms.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.awt.datatransfer.*;
|
|
||||||
|
|
||||||
public class ImageSelection implements Transferable {
|
|
||||||
|
|
||||||
private static final DataFlavor flavors[] =
|
|
||||||
{DataFlavor.imageFlavor};
|
|
||||||
|
|
||||||
private BufferedImage image;
|
|
||||||
|
|
||||||
public ImageSelection(BufferedImage image) {
|
|
||||||
this.image = image;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transferable
|
|
||||||
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
|
|
||||||
if (flavor.equals(flavors[0]) == false) {
|
|
||||||
throw new UnsupportedFlavorException(flavor);
|
|
||||||
}
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DataFlavor[] getTransferDataFlavors() {
|
|
||||||
return flavors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDataFlavorSupported(DataFlavor
|
|
||||||
flavor) {
|
|
||||||
return flavor.equals(flavors[0]);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
classdef PhysicsConstants < handle
|
|
||||||
properties (Constant)
|
|
||||||
% CODATA
|
|
||||||
PlanckConstant=6.62607015E-34;
|
|
||||||
PlanckConstantReduced=6.62607015E-34/(2*pi);
|
|
||||||
FineStructureConstant=7.2973525698E-3;
|
|
||||||
ElectronMass=9.10938291E-31;
|
|
||||||
GravitationalConstant=6.67384E-11;
|
|
||||||
ProtonMass=1.672621777E-27;
|
|
||||||
AtomicMassUnit=1.66053878283E-27;
|
|
||||||
BohrRadius=0.52917721092E-10;
|
|
||||||
BohrMagneton=927.400968E-26;
|
|
||||||
BoltzmannConstant=1.380649E-23;
|
|
||||||
StandardGravityAcceleration=9.80665;
|
|
||||||
SpeedOfLight=299792458;
|
|
||||||
StefanBoltzmannConstant=5.670373E-8;
|
|
||||||
ElectronCharge=1.602176634E-19;
|
|
||||||
VacuumPermeability=1.25663706212E-6;
|
|
||||||
DielectricConstant=8.8541878128E-12;
|
|
||||||
ElectronGyromagneticFactor=-2.00231930436153;
|
|
||||||
AvogadroConstant=6.02214076E23;
|
|
||||||
ZeroKelvin = 273.15;
|
|
||||||
GravitationalAcceleration = 9.80553;
|
|
||||||
|
|
||||||
% Dy specific constants
|
|
||||||
Dy164Mass = 163.929174751*1.66053878283E-27;
|
|
||||||
Dy164IsotopicAbundance = 0.2826;
|
|
||||||
BlueWavelength = 421.291e-9;
|
|
||||||
BlueLandegFactor = 1.22;
|
|
||||||
BlueLifetime = 4.94e-9;
|
|
||||||
BlueLinewidth = 1/4.94e-9;
|
|
||||||
RedWavelength = 626.086e-9;
|
|
||||||
RedLandegFactor = 1.29;
|
|
||||||
RedLifetime = 1.2e-6;
|
|
||||||
RedLinewidth = 1/1.2e-6;
|
|
||||||
PushBeamWaveLength = 626.086e-9;
|
|
||||||
PushBeamLifetime = 1.2e-6;
|
|
||||||
PushBeamLinewidth = 1/1.2e-6;
|
|
||||||
end
|
|
||||||
|
|
||||||
methods
|
|
||||||
function pc = PhysicsConstants()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,15 +0,0 @@
|
|||||||
function output = bringFiguresWithTagInForeground()
|
|
||||||
|
|
||||||
figure_handles = findobj('type','figure');
|
|
||||||
|
|
||||||
for idx = 1:length(figure_handles)
|
|
||||||
if ~isempty(figure_handles(idx).Tag)
|
|
||||||
figure(figure_handles(idx));
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if nargout > 0
|
|
||||||
output = figure_handles;
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,10 +0,0 @@
|
|||||||
function ret = calculateDistanceFromPointToLine(p0 , p1, p2)
|
|
||||||
p01 = p0 - p1;
|
|
||||||
p12 = p2 - p1;
|
|
||||||
CrossProduct = [p01(2)*p12(3) - p01(3)*p12(2), p01(3)*p12(1) - p01(1)*p12(3), p01(1)*p12(2) - p01(2)*p12(1)];
|
|
||||||
ret = norm(CrossProduct) / norm(p12);
|
|
||||||
|
|
||||||
%Height of parallelogram (Distance between point and line) = Area of parallelogram / Base
|
|
||||||
%Area = One side of parallelogram X Base
|
|
||||||
%ret = norm(cross(one side, base))./ norm(base);
|
|
||||||
end
|
|
@ -1,6 +0,0 @@
|
|||||||
function CellOut = convertstruct2cell(StructIn)
|
|
||||||
% CellOut = Convertstruct2cell(StructIn)
|
|
||||||
% converts a struct into a cell-matrix where the first column contains
|
|
||||||
% the fieldnames and the second the contents
|
|
||||||
CellOut = [fieldnames(StructIn) struct2cell(StructIn)]';
|
|
||||||
end
|
|
@ -1,18 +0,0 @@
|
|||||||
function ret = findAllZeroCrossings(x,y)
|
|
||||||
% Finds all Zero-crossing of the function y = f(x)
|
|
||||||
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0); % Returns Approximate Zero-Crossing Indices Of Argument Vector
|
|
||||||
zxidx = zci(y);
|
|
||||||
if ~isempty(zxidx)
|
|
||||||
for k1 = 1:numel(zxidx)
|
|
||||||
idxrng = max([1 zxidx(k1)-1]):min([zxidx(k1)+1 numel(y)]);
|
|
||||||
xrng = x(idxrng);
|
|
||||||
yrng = y(idxrng);
|
|
||||||
[yrng2, ~, jyrng] = unique(yrng); %yrng is a new array containing the unique values of yrng. jyrng contains the indices in yrng that correspond to the original vector. yrng = yrng2(jyrng)
|
|
||||||
xrng2 = accumarray(jyrng, xrng, [], @mean); %This function creates a new array "xrng2" by applying the function "@mean" to all elements in "xrng" that have identical indices in "jyrng". Any elements with identical X values will have identical indices in jyrng. Thus, this function creates a new array by averaging values with identical X values in the original array.
|
|
||||||
ret(k1) = interp1( yrng2(:), xrng2(:), 0, 'linear', 'extrap' );
|
|
||||||
end
|
|
||||||
else
|
|
||||||
warning('No zero crossings found!')
|
|
||||||
ret = nan;
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,191 +0,0 @@
|
|||||||
function figure_handle = getFigureByTag(tag_name, varargin)
|
|
||||||
% figure_handle = getFigureByTag(tag_name, varargin)
|
|
||||||
%
|
|
||||||
% Example code:
|
|
||||||
% f_h = getFigureByTag('survivalMeasurement','Name','Survival')
|
|
||||||
%
|
|
||||||
% clf(f_h);
|
|
||||||
% a_h = gca(f_h);
|
|
||||||
% xlim(a_h,[10,100]);
|
|
||||||
% % custom position
|
|
||||||
% f_h.Position = [4052.3 719.67 560 420];
|
|
||||||
|
|
||||||
assert(nargin>=1 && ischar(tag_name),'You must specify ``tag_name'' as a string.');
|
|
||||||
|
|
||||||
f_h = findobj('type','figure','tag',tag_name);
|
|
||||||
|
|
||||||
if isempty(f_h)
|
|
||||||
f_h = figure('Tag',tag_name,varargin{:});
|
|
||||||
|
|
||||||
defaultNewFigProperties = {'Color','w','NumberTitle','off','Name',sprintf('Fig. %d',f_h.Number)};
|
|
||||||
|
|
||||||
varargin = [defaultNewFigProperties,varargin];
|
|
||||||
else
|
|
||||||
f_h = f_h(1);
|
|
||||||
end
|
|
||||||
|
|
||||||
if ~isempty(varargin)
|
|
||||||
set(f_h,varargin{:});
|
|
||||||
end
|
|
||||||
|
|
||||||
addCopyButton(f_h);
|
|
||||||
|
|
||||||
if nargout > 0
|
|
||||||
figure_handle = f_h;
|
|
||||||
else
|
|
||||||
set(groot,'CurrentFigure',f_h);
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
function addCopyButton(f_h)
|
|
||||||
|
|
||||||
if(strcmp(f_h.ToolBar,'none'))
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
tb = findall(f_h,'Type','uitoolbar');
|
|
||||||
|
|
||||||
pt = findall(tb, 'tag', 'Custom.CopyPlot' );
|
|
||||||
if isempty(pt)
|
|
||||||
pt = uipushtool(tb);
|
|
||||||
else
|
|
||||||
pt = pt(1);
|
|
||||||
end
|
|
||||||
|
|
||||||
cdata = zeros(16,16,3);
|
|
||||||
|
|
||||||
% Evernote Logo
|
|
||||||
% cdata(:,:,1) =[255 NaN NaN NaN NaN 99 11 27 175 NaN NaN NaN NaN NaN NaN 255
|
|
||||||
% NaN NaN NaN 251 93 14 0 0 0 66 70 106 210 NaN NaN NaN
|
|
||||||
% NaN NaN NaN 42 0 43 0 0 0 0 0 0 20 185 NaN NaN
|
|
||||||
% NaN 243 56 0 42 82 0 0 0 0 0 0 0 45 NaN NaN
|
|
||||||
% NaN 156 44 64 113 65 0 0 0 0 0 0 0 32 NaN NaN
|
|
||||||
% 136 9 26 28 11 0 0 0 0 0 0 0 0 10 188 NaN
|
|
||||||
% 132 0 0 0 0 0 0 0 0 0 136 175 16 0 133 NaN
|
|
||||||
% NaN 28 0 0 0 0 0 0 0 0 152 238 50 0 124 NaN
|
|
||||||
% NaN 58 0 0 0 0 0 0 0 0 0 9 0 0 71 NaN
|
|
||||||
% NaN 175 0 0 0 0 0 61 15 0 0 0 0 0 100 NaN
|
|
||||||
% NaN NaN 143 12 0 0 0 210 195 87 17 0 0 0 126 NaN
|
|
||||||
% NaN NaN NaN 183 118 50 150 NaN NaN 110 219 78 0 0 160 NaN
|
|
||||||
% NaN NaN NaN NaN NaN NaN NaN 191 0 35 NaN 150 0 23 NaN NaN
|
|
||||||
% NaN NaN NaN NaN NaN NaN NaN 124 0 172 NaN 81 0 93 NaN NaN
|
|
||||||
% 255 NaN NaN NaN NaN NaN NaN 183 0 0 0 0 51 228 NaN 245
|
|
||||||
% 253 254 NaN NaN NaN NaN NaN NaN 156 63 45 100 NaN NaN 255 255]/255.;
|
|
||||||
%
|
|
||||||
%
|
|
||||||
% cdata(:,:,2) = [255 255 255 255 255 216 166 171 225 229 218 229 247 255 255 255
|
|
||||||
% 255 255 255 255 201 166 159 157 167 188 189 200 243 255 255 255
|
|
||||||
% 237 238 255 181 159 183 164 170 163 158 160 157 169 233 248 250
|
|
||||||
% 224 235 188 140 182 195 161 168 168 168 168 169 147 186 244 240
|
|
||||||
% 255 226 175 185 207 189 161 168 168 168 168 168 159 179 249 249
|
|
||||||
% 227 172 172 179 172 163 169 168 168 170 163 155 160 173 231 237
|
|
||||||
% 215 161 163 165 166 168 168 168 168 162 215 228 172 163 209 219
|
|
||||||
% 248 178 159 168 168 168 168 168 168 159 220 249 185 158 208 222
|
|
||||||
% 249 192 151 169 168 168 169 160 163 172 163 159 166 167 194 204
|
|
||||||
% 246 229 155 157 168 169 159 188 174 154 162 167 166 166 202 214
|
|
||||||
% 212 231 218 168 157 153 165 255 242 190 171 159 167 166 207 220
|
|
||||||
% 218 203 251 243 206 181 230 210 208 207 242 196 154 168 223 232
|
|
||||||
% 255 224 232 250 237 214 244 194 152 178 255 223 145 175 250 252
|
|
||||||
% 255 255 244 239 222 213 240 214 149 228 254 199 136 203 244 232
|
|
||||||
% 255 255 255 246 231 246 246 232 165 159 167 147 184 253 254 242
|
|
||||||
% 253 254 255 255 254 255 255 255 231 183 178 199 249 255 255 255]/255.;
|
|
||||||
%
|
|
||||||
%
|
|
||||||
% cdata(:,:,3) = [255 255 255 255 255 117 38 50 187 211 170 190 234 255 255 255
|
|
||||||
% 255 254 255 255 120 51 27 20 39 97 98 122 220 255 255 255
|
|
||||||
% 238 252 246 73 22 71 37 49 35 20 24 18 49 196 231 231
|
|
||||||
% 232 242 86 0 78 108 29 45 45 45 45 46 0 82 214 201
|
|
||||||
% 255 175 63 85 139 98 27 45 45 45 45 45 23 72 233 231
|
|
||||||
% 167 51 57 72 55 32 47 45 45 50 34 14 27 57 201 218
|
|
||||||
% 154 30 33 38 39 45 45 45 45 31 157 188 53 34 153 180
|
|
||||||
% 234 67 24 45 45 45 45 44 45 24 169 241 83 20 146 182
|
|
||||||
% 241 99 4 48 45 45 47 28 35 53 32 26 39 44 104 127
|
|
||||||
% 238 192 14 20 45 47 27 97 56 10 29 44 41 40 127 158
|
|
||||||
% 214 253 169 37 20 16 34 218 207 105 55 23 42 40 147 182
|
|
||||||
% 218 214 241 201 138 71 177 225 181 130 224 107 12 45 175 197
|
|
||||||
% 255 233 202 218 212 132 230 196 27 61 255 172 0 64 240 242
|
|
||||||
% 255 255 219 197 176 160 237 143 0 195 245 110 0 123 230 230
|
|
||||||
% 255 255 255 227 197 241 244 202 36 24 39 0 81 228 242 245
|
|
||||||
% 253 254 255 255 254 255 255 255 191 78 71 121 221 255 255 255]/255.;
|
|
||||||
|
|
||||||
%OneNote logo
|
|
||||||
|
|
||||||
cdata(:,:,1) =[255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
|
|
||||||
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
|
|
||||||
255 255 255 255 245 213 213 213 213 213 213 213 184 184 215 255
|
|
||||||
255 255 255 255 241 213 213 213 213 213 213 213 184 184 208 255
|
|
||||||
255 233 204 204 194 176 176 185 213 213 213 213 184 184 208 255
|
|
||||||
255 154 101 101 101 101 101 103 213 213 213 206 162 162 193 255
|
|
||||||
255 152 101 183 116 152 115 101 213 213 213 206 162 162 193 255
|
|
||||||
255 152 101 207 189 178 122 101 213 213 213 206 162 162 193 255
|
|
||||||
255 152 101 199 152 224 122 101 213 213 213 195 128 128 170 255
|
|
||||||
255 152 101 166 101 183 115 101 213 213 213 195 128 128 170 255
|
|
||||||
255 154 101 101 101 101 101 103 213 213 213 195 128 128 170 255
|
|
||||||
255 233 204 204 194 176 176 185 213 213 213 183 95 95 148 255
|
|
||||||
255 255 255 255 241 213 213 213 213 213 213 183 94 94 148 255
|
|
||||||
255 255 255 255 245 213 213 213 213 213 213 183 94 94 163 255
|
|
||||||
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
|
|
||||||
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255]/255.;
|
|
||||||
|
|
||||||
|
|
||||||
cdata(:,:,2) =[255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
|
|
||||||
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
|
|
||||||
255 255 255 255 219 112 110 110 110 110 110 134 84 84 158 255
|
|
||||||
255 255 255 255 207 110 110 110 110 110 110 134 84 84 141 255
|
|
||||||
255 222 178 178 146 81 81 88 110 110 110 134 84 84 141 255
|
|
||||||
255 102 23 23 23 23 23 24 110 110 110 125 58 58 123 255
|
|
||||||
255 100 23 147 46 100 44 23 110 110 110 125 58 58 123 255
|
|
||||||
255 100 23 183 156 139 55 23 110 110 110 125 58 58 123 255
|
|
||||||
255 100 23 170 99 208 55 23 110 110 110 119 38 38 109 255
|
|
||||||
255 100 23 121 23 146 44 23 110 110 110 119 38 38 109 255
|
|
||||||
255 102 23 23 23 23 23 24 110 110 110 119 38 38 109 255
|
|
||||||
255 222 178 178 146 81 81 88 110 110 110 118 37 37 109 255
|
|
||||||
255 255 255 255 207 110 110 110 110 110 110 118 37 37 110 255
|
|
||||||
255 255 255 255 219 112 110 110 110 110 110 118 37 37 131 255
|
|
||||||
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
|
|
||||||
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255]/255.;
|
|
||||||
|
|
||||||
|
|
||||||
cdata(:,:,3) =[255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
|
|
||||||
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
|
|
||||||
255 255 255 255 255 255 255 255 255 255 255 246 229 229 240 255
|
|
||||||
255 255 255 255 255 255 255 255 255 255 255 246 229 229 238 255
|
|
||||||
255 242 224 224 224 224 224 232 255 255 255 246 229 229 238 255
|
|
||||||
255 194 163 163 163 163 163 164 255 255 255 244 223 223 234 255
|
|
||||||
255 194 163 212 172 194 171 163 255 255 255 244 223 223 234 255
|
|
||||||
255 194 163 226 216 209 176 163 255 255 255 244 223 223 234 255
|
|
||||||
255 194 163 221 193 236 176 163 255 255 255 240 209 209 224 255
|
|
||||||
255 194 163 202 163 212 171 163 255 255 255 240 209 209 224 255
|
|
||||||
255 194 163 163 163 163 163 164 255 255 255 240 209 209 224 255
|
|
||||||
255 242 224 224 224 224 224 232 255 255 255 223 161 161 192 255
|
|
||||||
255 255 255 255 255 255 255 255 255 255 255 223 160 160 192 255
|
|
||||||
255 255 255 255 255 255 255 255 255 255 255 223 160 160 201 255
|
|
||||||
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
|
|
||||||
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255]/255.;
|
|
||||||
|
|
||||||
|
|
||||||
pt.Tag = 'Custom.CopyPlot';
|
|
||||||
pt.CData = cdata;
|
|
||||||
pt.Separator = true;
|
|
||||||
pt.ClickedCallback = @copyToClipboard;
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
function copyToClipboard(~,~)
|
|
||||||
fig_h = get(get(gcbo,'Parent'),'Parent');
|
|
||||||
if strcmp(fig_h.WindowStyle,'docked')
|
|
||||||
if ismac || ispc
|
|
||||||
matlab.graphics.internal.copyFigureHelper(fig_h);
|
|
||||||
else
|
|
||||||
%warning('Copy function to the clipboard only works if the figure is undocked.');
|
|
||||||
Helper.screencapture(fig_h,[],'clipboard');
|
|
||||||
end
|
|
||||||
else
|
|
||||||
pos = fig_h.Position;
|
|
||||||
Helper.screencapture(fig_h,[],'clipboard','position',[7,7,pos(3)-2,pos(4)]);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
|||||||
function Y = ode5(odefun,tspan,y0,varargin)
|
|
||||||
%ODE5 Solve differential equations with a non-adaptive method of order 5.
|
|
||||||
% Y = ODE5(ODEFUN,TSPAN,Y0) with TSPAN = [T1, T2, T3, ... TN] integrates
|
|
||||||
% the system of differential equations y' = f(t,y) by stepping from T0 to
|
|
||||||
% T1 to TN. Function ODEFUN(T,Y) must return f(t,y) in a column vector.
|
|
||||||
% The vector Y0 is the initial conditions at T0. Each row in the solution
|
|
||||||
% array Y corresponds to a time specified in TSPAN.
|
|
||||||
%
|
|
||||||
% Y = ODE5(ODEFUN,TSPAN,Y0,P1,P2...) passes the additional parameters
|
|
||||||
% P1,P2... to the derivative function as ODEFUN(T,Y,P1,P2...).
|
|
||||||
%
|
|
||||||
% This is a non-adaptive solver. The step sequence is determined by TSPAN
|
|
||||||
% but the derivative function ODEFUN is evaluated multiple times per step.
|
|
||||||
% The solver implements the Dormand-Prince method of order 5 in a general
|
|
||||||
% framework of explicit Runge-Kutta methods.
|
|
||||||
%
|
|
||||||
% Example
|
|
||||||
% tspan = 0:0.1:20;
|
|
||||||
% y = ode5(@vdp1,tspan,[2 0]);
|
|
||||||
% plot(tspan,y(:,1));
|
|
||||||
% solves the system y' = vdp1(t,y) with a constant step size of 0.1,
|
|
||||||
% and plots the first component of the solution.
|
|
||||||
|
|
||||||
if ~isnumeric(tspan)
|
|
||||||
error('TSPAN should be a vector of integration steps.');
|
|
||||||
end
|
|
||||||
|
|
||||||
if ~isnumeric(y0)
|
|
||||||
error('Y0 should be a vector of initial conditions.');
|
|
||||||
end
|
|
||||||
|
|
||||||
h = diff(tspan);
|
|
||||||
if any(sign(h(1))*h <= 0)
|
|
||||||
error('Entries of TSPAN are not in order.')
|
|
||||||
end
|
|
||||||
|
|
||||||
try
|
|
||||||
f0 = feval(odefun,tspan(1),y0,varargin{:});
|
|
||||||
catch
|
|
||||||
msg = ['Unable to evaluate the ODEFUN at t0,y0. ',lasterr];
|
|
||||||
error(msg);
|
|
||||||
end
|
|
||||||
|
|
||||||
y0 = y0(:); % Make a column vector.
|
|
||||||
if ~isequal(size(y0),size(f0))
|
|
||||||
error('Inconsistent sizes of Y0 and f(t0,y0).');
|
|
||||||
end
|
|
||||||
|
|
||||||
neq = length(y0);
|
|
||||||
N = length(tspan);
|
|
||||||
Y = zeros(neq,N);
|
|
||||||
|
|
||||||
% Method coefficients -- Butcher's tableau
|
|
||||||
%
|
|
||||||
% C | A
|
|
||||||
% --+---
|
|
||||||
% | B
|
|
||||||
|
|
||||||
C = [1/5; 3/10; 4/5; 8/9; 1];
|
|
||||||
|
|
||||||
A = [ 1/5, 0, 0, 0, 0
|
|
||||||
3/40, 9/40, 0, 0, 0
|
|
||||||
44/45 -56/15, 32/9, 0, 0
|
|
||||||
19372/6561, -25360/2187, 64448/6561, -212/729, 0
|
|
||||||
9017/3168, -355/33, 46732/5247, 49/176, -5103/18656];
|
|
||||||
|
|
||||||
B = [35/384, 0, 500/1113, 125/192, -2187/6784, 11/84];
|
|
||||||
|
|
||||||
% More convenient storage
|
|
||||||
A = A.';
|
|
||||||
B = B(:);
|
|
||||||
|
|
||||||
nstages = length(B);
|
|
||||||
F = zeros(neq,nstages);
|
|
||||||
|
|
||||||
Y(:,1) = y0;
|
|
||||||
for i = 2:N
|
|
||||||
ti = tspan(i-1);
|
|
||||||
hi = h(i-1);
|
|
||||||
yi = Y(:,i-1);
|
|
||||||
|
|
||||||
% General explicit Runge-Kutta framework
|
|
||||||
F(:,1) = feval(odefun,ti,yi,varargin{:});
|
|
||||||
for stage = 2:nstages
|
|
||||||
tstage = ti + C(stage-1)*hi;
|
|
||||||
ystage = yi + F(:,1:stage-1)*(hi*A(1:stage-1,stage-1));
|
|
||||||
F(:,stage) = feval(odefun,tstage,ystage,varargin{:});
|
|
||||||
end
|
|
||||||
Y(:,i) = yi + F*(hi*B);
|
|
||||||
|
|
||||||
end
|
|
||||||
Y = Y.';
|
|
@ -1,55 +0,0 @@
|
|||||||
cmap = zeros(16,16,3);
|
|
||||||
|
|
||||||
cmap(:,:,1) = [0.0000 0.0118 0.4510 0.0039 0.2078 0.1569 0.4078 0.4431 0.4510 0.1922 0.4235 0.4196 0.2235 0.4235 0.4039 0.4392
|
|
||||||
0.4471 0.1647 0.4157 0.0000 0.0235 0.4353 0.0314 0.4314 0.0196 0.2392 0.0667 0.0392 0.4431 0.3804 0.2941 0.4275
|
|
||||||
0.3686 0.3608 0.2000 0.2824 0.3059 0.0549 0.1804 0.1882 0.4392 0.4314 0.3255 0.0078 0.0902 0.1961 0.4353 0.1412
|
|
||||||
0.2314 0.3647 0.0353 0.3804 0.1647 0.2431 0.1686 0.2745 0.2980 0.4235 0.3922 0.4157 0.2784 0.3333 0.2510 0.0588
|
|
||||||
0.1020 0.0745 0.2549 0.0471 0.1216 0.4000 0.3961 0.2627 0.1098 0.1725 0.3098 0.4314 0.3529 0.3412 0.0784 0.0824
|
|
||||||
0.4471 0.1490 0.1804 0.3529 0.2196 0.3137 0.3255 0.0941 0.0078 0.3294 0.3765 0.2706 0.0510 0.0157 0.4275 0.1176
|
|
||||||
0.1294 0.1333 0.1725 0.3451 0.2118 0.3843 0.1255 0.1569 0.2118 0.1608 0.0353 0.2039 0.1608 0.4510 1.0000 0.8000
|
|
||||||
0.9882 0.6510 0.9961 0.4549 0.4549 0.6824 0.7882 0.5686 0.5373 0.5490 0.7765 0.7137 0.8510 0.7176 0.5020 0.4902
|
|
||||||
0.8941 0.9020 0.4745 0.8980 0.9098 0.4824 0.6471 0.6353 0.9922 0.9647 0.6353 0.4588 0.9647 0.9020 0.4980 0.8118
|
|
||||||
0.5059 0.4941 0.9686 0.4863 0.5451 0.9725 0.8980 0.5451 0.5333 0.6824 0.4588 0.8196 0.8314 0.8980 0.8941 0.9961
|
|
||||||
0.5255 0.8392 0.9804 0.5216 0.8588 0.8078 0.5176 0.7647 0.5608 0.9725 0.9059 0.4627 0.9882 0.8275 0.7725 0.8745
|
|
||||||
0.8235 0.8431 0.7373 1.0000 0.5137 0.4706 0.4784 0.7412 0.8863 0.9373 0.5529 0.5804 0.4510 0.9255 0.8235 0.8667
|
|
||||||
0.7569 0.8824 0.5294 0.5176 0.5373 0.9569 0.5294 0.4824 0.5098 0.5137 0.5569 0.8471 0.5098 0.9490 0.8706 0.9412
|
|
||||||
0.4902 0.6000 0.6980 0.7882 0.5490 0.7216 0.6431 0.4824 0.5569 0.4667 0.6627 0.9922 0.7804 0.8039 0.6275 0.7333
|
|
||||||
0.5725 0.5647 0.8549 0.7529 0.6235 0.8784 0.5922 0.7294 0.6118 0.7922 0.7843 0.6667 0.9294 0.6902 0.6784 0.9176
|
|
||||||
0.6706 0.7490 0.7961 0.5882 0.8627 0.4627 0.6196 0.7059 0.6078 0.9765 0.6549 0.6863 0.5373 0.7098 0.7176 0.7765];
|
|
||||||
|
|
||||||
cmap(:,:,2) = [0.0000 0.0078 0.2157 0.0000 0.0980 0.0745 0.1922 0.2157 0.2157 0.0902 0.2000 0.1961 0.1059 0.2039 0.1882 0.2078
|
|
||||||
0.2078 0.0784 0.2000 0.0000 0.0118 0.2118 0.0157 0.2039 0.0078 0.1137 0.0314 0.0196 0.2118 0.1804 0.1373 0.2078
|
|
||||||
0.1765 0.1725 0.0941 0.1333 0.1451 0.0275 0.0863 0.0902 0.2078 0.2078 0.1529 0.0039 0.0431 0.0941 0.2039 0.0667
|
|
||||||
0.1098 0.1725 0.0157 0.1804 0.0784 0.1137 0.0824 0.1333 0.1412 0.2000 0.1882 0.2000 0.1333 0.1569 0.1176 0.0275
|
|
||||||
0.0471 0.0353 0.1216 0.0196 0.0588 0.1922 0.1882 0.1255 0.0510 0.0824 0.1451 0.2039 0.1686 0.1647 0.0392 0.0392
|
|
||||||
0.2157 0.0706 0.0863 0.1686 0.1020 0.1490 0.1529 0.0431 0.0039 0.1569 0.1804 0.1255 0.0235 0.0078 0.2000 0.0549
|
|
||||||
0.0627 0.0627 0.0824 0.1647 0.1020 0.1843 0.0588 0.0745 0.1020 0.0784 0.0157 0.0980 0.0784 0.2157 1.0000 0.7137
|
|
||||||
0.9843 0.4980 0.9961 0.2235 0.2196 0.5412 0.6980 0.3843 0.3373 0.3569 0.6824 0.5922 0.7843 0.6000 0.2902 0.2706
|
|
||||||
0.8510 0.8588 0.2471 0.8549 0.8667 0.2627 0.4980 0.4784 0.9843 0.9490 0.4745 0.2235 0.9451 0.8627 0.2824 0.7333
|
|
||||||
0.2941 0.2784 0.9529 0.2667 0.3490 0.9569 0.8510 0.3490 0.3333 0.5451 0.2275 0.7412 0.7608 0.8549 0.8471 0.9922
|
|
||||||
0.3255 0.7686 0.9725 0.3176 0.8000 0.7255 0.3098 0.6627 0.3725 0.9647 0.8627 0.2314 0.9804 0.7529 0.6745 0.8235
|
|
||||||
0.7451 0.7765 0.6235 0.9961 0.3020 0.2431 0.2510 0.6314 0.8392 0.9098 0.3608 0.4000 0.2196 0.8902 0.7490 0.8078
|
|
||||||
0.6549 0.8353 0.3294 0.3137 0.3412 0.9373 0.3255 0.2588 0.2980 0.3059 0.3686 0.7843 0.3020 0.9255 0.8157 0.9176
|
|
||||||
0.2745 0.4275 0.5686 0.6980 0.3569 0.6039 0.4863 0.2627 0.3647 0.2392 0.5137 0.9922 0.6863 0.7216 0.4706 0.6196
|
|
||||||
0.3882 0.3765 0.7882 0.6471 0.4588 0.8275 0.4157 0.6118 0.4431 0.7059 0.6902 0.5255 0.8980 0.5569 0.5412 0.8824
|
|
||||||
0.5333 0.6392 0.7098 0.4078 0.8039 0.2314 0.4549 0.5804 0.4392 0.9647 0.5059 0.5529 0.3373 0.5882 0.5961 0.6784];
|
|
||||||
|
|
||||||
cmap(:,:,3) = [0.0000 0.0157 0.4980 0.0039 0.2314 0.1725 0.4627 0.5020 0.5020 0.2196 0.4745 0.4706 0.2510 0.4784 0.4510 0.4980
|
|
||||||
0.4941 0.1882 0.4667 0.0000 0.0275 0.4941 0.0353 0.4902 0.0196 0.2667 0.0745 0.0471 0.4902 0.4314 0.3294 0.4784
|
|
||||||
0.4196 0.4000 0.2235 0.3216 0.3412 0.0627 0.2039 0.2118 0.4863 0.4863 0.3608 0.0078 0.1020 0.2196 0.4824 0.1569
|
|
||||||
0.2588 0.4118 0.0392 0.4235 0.1843 0.2745 0.1882 0.3059 0.3373 0.4784 0.4392 0.4627 0.3137 0.3765 0.2824 0.0667
|
|
||||||
0.1137 0.0824 0.2863 0.0510 0.1373 0.4510 0.4471 0.2941 0.1216 0.1961 0.3490 0.4824 0.3961 0.3804 0.0902 0.0941
|
|
||||||
0.4980 0.1647 0.2000 0.4000 0.2431 0.3529 0.3647 0.1059 0.0118 0.3686 0.4196 0.3020 0.0549 0.0196 0.4824 0.1294
|
|
||||||
0.1451 0.1529 0.1922 0.3882 0.2392 0.4353 0.1412 0.1765 0.2353 0.1804 0.0353 0.2275 0.1843 0.5059 1.0000 0.8196
|
|
||||||
0.9882 0.6863 0.9961 0.5098 0.5098 0.7137 0.8118 0.6118 0.5843 0.5922 0.8000 0.7412 0.8627 0.7451 0.5529 0.5412
|
|
||||||
0.9059 0.9137 0.5255 0.9098 0.9176 0.5333 0.6824 0.6706 0.9922 0.9686 0.6706 0.5098 0.9647 0.9137 0.5490 0.8314
|
|
||||||
0.5569 0.5451 0.9725 0.5373 0.5922 0.9725 0.9059 0.5882 0.5804 0.7137 0.5137 0.8353 0.8510 0.9059 0.9020 0.9961
|
|
||||||
0.5725 0.8549 0.9843 0.5725 0.8745 0.8275 0.5647 0.7882 0.6039 0.9765 0.9137 0.5176 0.9882 0.8431 0.7961 0.8863
|
|
||||||
0.8392 0.8588 0.7647 1.0000 0.5608 0.5216 0.5294 0.7686 0.8980 0.9412 0.6000 0.6235 0.5059 0.9333 0.8431 0.8784
|
|
||||||
0.7804 0.8941 0.5765 0.5686 0.5843 0.9608 0.5765 0.5333 0.5569 0.5647 0.6039 0.8627 0.5608 0.9569 0.8863 0.9490
|
|
||||||
0.5412 0.6392 0.7294 0.8078 0.5961 0.7490 0.6784 0.5373 0.6000 0.5216 0.6941 0.9922 0.8039 0.8235 0.6667 0.7608
|
|
||||||
0.6157 0.6078 0.8667 0.7765 0.6588 0.8902 0.6314 0.7569 0.6510 0.8157 0.8039 0.7020 0.9373 0.7216 0.7098 0.9255
|
|
||||||
0.7059 0.7725 0.8196 0.6314 0.8784 0.5137 0.6549 0.7373 0.6471 0.9804 0.6902 0.7176 0.5804 0.7412 0.7451 0.8000];
|
|
||||||
|
|
||||||
%%
|
|
||||||
[cdata, cmap] = imread('onenote.png');
|
|
@ -1,148 +0,0 @@
|
|||||||
% Copyright (c) 2019 Andrea Alberti
|
|
||||||
%
|
|
||||||
% All rights reserved.
|
|
||||||
classdef parforNotifications < handle
|
|
||||||
properties
|
|
||||||
N; % number of iterations
|
|
||||||
text = 'Please wait ...'; % text to show
|
|
||||||
width = 50;
|
|
||||||
showWarning = true;
|
|
||||||
end
|
|
||||||
properties (GetAccess = public, SetAccess = private)
|
|
||||||
n;
|
|
||||||
end
|
|
||||||
properties (Access = private)
|
|
||||||
inProgress = false;
|
|
||||||
percent;
|
|
||||||
DataQueue;
|
|
||||||
usePercent;
|
|
||||||
Nstr;
|
|
||||||
NstrL;
|
|
||||||
lastComment;
|
|
||||||
end
|
|
||||||
methods
|
|
||||||
function this = parforNotifications()
|
|
||||||
this.DataQueue = parallel.pool.DataQueue;
|
|
||||||
afterEach(this.DataQueue, @this.updateStatus);
|
|
||||||
end
|
|
||||||
% Start progress bar
|
|
||||||
function PB_start(this,N,varargin)
|
|
||||||
assert(isscalar(N) && isnumeric(N) && N == floor(N) && N>0, 'Error: ''N'' must be a scalar positive integer.');
|
|
||||||
|
|
||||||
this.N = N;
|
|
||||||
|
|
||||||
p = inputParser;
|
|
||||||
addParameter(p,'message','Please wait: ');
|
|
||||||
addParameter(p,'usePercentage',true);
|
|
||||||
|
|
||||||
parse(p,varargin{:});
|
|
||||||
|
|
||||||
this.text = p.Results.message;
|
|
||||||
assert(ischar(this.text), 'Error: ''Message'' must be a string.');
|
|
||||||
|
|
||||||
this.usePercent = p.Results.usePercentage;
|
|
||||||
assert(isscalar(this.usePercent) && islogical(this.usePercent), 'Error: ''usePercentage'' must be a logical scalar.');
|
|
||||||
|
|
||||||
this.percent = 0;
|
|
||||||
this.n = 0;
|
|
||||||
this.lastComment = '';
|
|
||||||
if this.usePercent
|
|
||||||
fprintf('%s [%s]: %3d%%\n',this.text, char(32*ones(1,this.width)),0);
|
|
||||||
else
|
|
||||||
this.Nstr = sprintf('%d',this.N);
|
|
||||||
this.NstrL = numel(this.Nstr);
|
|
||||||
fprintf('%s [%s]: %s/%s\n',this.text, char(32*ones(1,this.width)),[char(32*ones(1,this.NstrL-1)),'0'],this.Nstr);
|
|
||||||
end
|
|
||||||
|
|
||||||
this.inProgress = true;
|
|
||||||
end
|
|
||||||
% Iterate progress bar
|
|
||||||
function PB_iterate(this,str)
|
|
||||||
if nargin == 1
|
|
||||||
send(this.DataQueue,'');
|
|
||||||
else
|
|
||||||
send(this.DataQueue,str);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function warning(this,warn_id,msg)
|
|
||||||
if this.showWarning
|
|
||||||
msg = struct('Action','Warning','Id',warn_id,'Message',msg);
|
|
||||||
send(this.DataQueue,msg);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function PB_reprint(this)
|
|
||||||
p = round(100*this.n/this.N);
|
|
||||||
|
|
||||||
this.percent = p;
|
|
||||||
|
|
||||||
cursor_pos=1+round((this.width-1)*p/100);
|
|
||||||
|
|
||||||
if p < 100
|
|
||||||
sep_char = '|';
|
|
||||||
else
|
|
||||||
sep_char = '.';
|
|
||||||
end
|
|
||||||
|
|
||||||
if this.usePercent
|
|
||||||
fprintf('%s [%s%s%s]: %3d%%\n', this.text, char(46*ones(1,cursor_pos-1)), sep_char, char(32*ones(1,this.width-cursor_pos)),p);
|
|
||||||
else
|
|
||||||
nstr=sprintf('%d',this.n);
|
|
||||||
fprintf('%s [%s%s%s]: %s/%s\n', this.text, char(46*ones(1,cursor_pos-1)), sep_char, char(32*ones(1,this.width-cursor_pos)),[char(32*ones(1,this.NstrL-numel(nstr))),nstr],this.Nstr);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function updateStatus(this,data)
|
|
||||||
|
|
||||||
if ischar(data)
|
|
||||||
|
|
||||||
this.n = this.n + 1;
|
|
||||||
|
|
||||||
p = round(100*this.n/this.N);
|
|
||||||
|
|
||||||
if p >= this.percent+1 || this.n == this.N
|
|
||||||
this.percent = p;
|
|
||||||
|
|
||||||
cursor_pos=1+round((this.width-1)*p/100);
|
|
||||||
|
|
||||||
if p < 100
|
|
||||||
sep_char = '|';
|
|
||||||
else
|
|
||||||
sep_char = '.';
|
|
||||||
end
|
|
||||||
|
|
||||||
if ~isempty(data)
|
|
||||||
comment = [' (',data,')'];
|
|
||||||
else
|
|
||||||
comment = '';
|
|
||||||
end
|
|
||||||
|
|
||||||
if this.usePercent
|
|
||||||
fprintf('%s%s%s%s]: %3d%%%s\n',char(8*ones(1,58+numel(this.lastComment))), char(46*ones(1,cursor_pos-1)), sep_char, char(32*ones(1,this.width-cursor_pos)),p,comment);
|
|
||||||
else
|
|
||||||
nstr=sprintf('%d',this.n);
|
|
||||||
fprintf('%s%s%s%s]: %s/%s%s\n',char(8*ones(1,55+2*numel(this.Nstr)+numel(this.lastComment))), char(46*ones(1,cursor_pos-1)), sep_char, char(32*ones(1,this.width-cursor_pos)),[char(32*ones(1,this.NstrL-numel(nstr))),nstr],this.Nstr,comment)
|
|
||||||
end
|
|
||||||
|
|
||||||
this.lastComment = comment;
|
|
||||||
|
|
||||||
|
|
||||||
if p == 100
|
|
||||||
this.inProgress = false;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
else
|
|
||||||
switch data.Action
|
|
||||||
case 'Warning'
|
|
||||||
warning(data.Id,[data.Message,newline]);
|
|
||||||
if this.inProgress
|
|
||||||
this.PB_reprint();
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
@ -1,820 +0,0 @@
|
|||||||
function imageData = screencapture(varargin)
|
|
||||||
% screencapture - get a screen-capture of a figure frame, component handle, or screen area rectangle
|
|
||||||
%
|
|
||||||
% ScreenCapture gets a screen-capture of any Matlab GUI handle (including desktop,
|
|
||||||
% figure, axes, image or uicontrol), or a specified area rectangle located relative to
|
|
||||||
% the specified handle. Screen area capture is possible by specifying the root (desktop)
|
|
||||||
% handle (=0). The output can be either to an image file or to a Matlab matrix (useful
|
|
||||||
% for displaying via imshow() or for further processing) or to the system clipboard.
|
|
||||||
% This utility also enables adding a toolbar button for easy interactive screen-capture.
|
|
||||||
%
|
|
||||||
% Syntax:
|
|
||||||
% imageData = screencapture(handle, position, target, 'PropName',PropValue, ...)
|
|
||||||
%
|
|
||||||
% Input Parameters:
|
|
||||||
% handle - optional handle to be used for screen-capture origin.
|
|
||||||
% If empty/unsupplied then current figure (gcf) will be used.
|
|
||||||
% position - optional position array in pixels: [x,y,width,height].
|
|
||||||
% If empty/unsupplied then the handle's position vector will be used.
|
|
||||||
% If both handle and position are empty/unsupplied then the position
|
|
||||||
% will be retrieved via interactive mouse-selection.
|
|
||||||
% If handle is an image, then position is in data (not pixel) units, so the
|
|
||||||
% captured region remains the same after figure/axes resize (like imcrop)
|
|
||||||
% target - optional filename for storing the screen-capture, or the
|
|
||||||
% 'clipboard'/'printer' strings.
|
|
||||||
% If empty/unsupplied then no output to file will be done.
|
|
||||||
% The file format will be determined from the extension (JPG/PNG/...).
|
|
||||||
% Supported formats are those supported by the imwrite function.
|
|
||||||
% 'PropName',PropValue -
|
|
||||||
% optional list of property pairs (e.g., 'target','myImage.png','pos',[10,20,30,40],'handle',gca)
|
|
||||||
% PropNames may be abbreviated and are case-insensitive.
|
|
||||||
% PropNames may also be given in whichever order.
|
|
||||||
% Supported PropNames are:
|
|
||||||
% - 'handle' (default: gcf handle)
|
|
||||||
% - 'position' (default: gcf position array)
|
|
||||||
% - 'target' (default: '')
|
|
||||||
% - 'toolbar' (figure handle; default: gcf)
|
|
||||||
% this adds a screen-capture button to the figure's toolbar
|
|
||||||
% If this parameter is specified, then no screen-capture
|
|
||||||
% will take place and the returned imageData will be [].
|
|
||||||
%
|
|
||||||
% Output parameters:
|
|
||||||
% imageData - image data in a format acceptable by the imshow function
|
|
||||||
% If neither target nor imageData were specified, the user will be
|
|
||||||
% asked to interactively specify the output file.
|
|
||||||
%
|
|
||||||
% Examples:
|
|
||||||
% imageData = screencapture; % interactively select screen-capture rectangle
|
|
||||||
% imageData = screencapture(hListbox); % capture image of a uicontrol
|
|
||||||
% imageData = screencapture(0, [20,30,40,50]); % capture a small desktop region
|
|
||||||
% imageData = screencapture(gcf,[20,30,40,50]); % capture a small figure region
|
|
||||||
% imageData = screencapture(gca,[10,20,30,40]); % capture a small axes region
|
|
||||||
% imshow(imageData); % display the captured image in a matlab figure
|
|
||||||
% imwrite(imageData,'myImage.png'); % save the captured image to file
|
|
||||||
% img = imread('cameraman.tif');
|
|
||||||
% hImg = imshow(img);
|
|
||||||
% screencapture(hImg,[60,35,140,80]); % capture a region of an image
|
|
||||||
% screencapture(gcf,[],'myFigure.jpg'); % capture the entire figure into file
|
|
||||||
% screencapture(gcf,[],'clipboard'); % capture the entire figure into clipboard
|
|
||||||
% screencapture(gcf,[],'printer'); % print the entire figure
|
|
||||||
% screencapture('handle',gcf,'target','myFigure.jpg'); % same as previous, save to file
|
|
||||||
% screencapture('handle',gcf,'target','clipboard'); % same as previous, copy to clipboard
|
|
||||||
% screencapture('handle',gcf,'target','printer'); % same as previous, send to printer
|
|
||||||
% screencapture('toolbar',gcf); % adds a screen-capture button to gcf's toolbar
|
|
||||||
% screencapture('toolbar',[],'target','sc.bmp'); % same with default output filename
|
|
||||||
%
|
|
||||||
% Technical description:
|
|
||||||
% http://UndocumentedMatlab.com/blog/screencapture-utility/
|
|
||||||
%
|
|
||||||
% Bugs and suggestions:
|
|
||||||
% Please send to Yair Altman (altmany at gmail dot com)
|
|
||||||
%
|
|
||||||
% See also:
|
|
||||||
% imshow, imwrite, print
|
|
||||||
%
|
|
||||||
% Release history:
|
|
||||||
% 1.17 2016-05-16: Fix annoying warning about JavaFrame property becoming obsolete someday (yes, we know...)
|
|
||||||
% 1.16 2016-04-19: Fix for deployed application suggested by Dwight Bartholomew
|
|
||||||
% 1.10 2014-11-25: Added the 'print' target
|
|
||||||
% 1.9 2014-11-25: Fix for saving GIF files
|
|
||||||
% 1.8 2014-11-16: Fixes for R2014b
|
|
||||||
% 1.7 2014-04-28: Fixed bug when capturing interactive selection
|
|
||||||
% 1.6 2014-04-22: Only enable image formats when saving to an unspecified file via uiputfile
|
|
||||||
% 1.5 2013-04-18: Fixed bug in capture of non-square image; fixes for Win64
|
|
||||||
% 1.4 2013-01-27: Fixed capture of Desktop (root); enabled rbbox anywhere on desktop (not necesarily in a Matlab figure); enabled output to clipboard (based on Jiro Doke's imclipboard utility); edge-case fixes; added Java compatibility check
|
|
||||||
% 1.3 2012-07-23: Capture current object (uicontrol/axes/figure) if w=h=0 (e.g., by clicking a single point); extra input args sanity checks; fix for docked windows and image axes; include axes labels & ticks by default when capturing axes; use data-units position vector when capturing images; many edge-case fixes
|
|
||||||
% 1.2 2011-01-16: another performance boost (thanks to Jan Simon); some compatibility fixes for Matlab 6.5 (untested)
|
|
||||||
% 1.1 2009-06-03: Handle missing output format; performance boost (thanks to Urs); fix minor root-handle bug; added toolbar button option
|
|
||||||
% 1.0 2009-06-02: First version posted on <a href="http://www.mathworks.com/matlabcentral/fileexchange/authors/27420">MathWorks File Exchange</a>
|
|
||||||
|
|
||||||
% License to use and modify this code is granted freely to all interested, as long as the original author is
|
|
||||||
% referenced and attributed as such. The original author maintains the right to be solely associated with this work.
|
|
||||||
|
|
||||||
% Programmed and Copyright by Yair M. Altman: altmany(at)gmail.com
|
|
||||||
% $Revision: 1.17 $ $Date: 2016/05/16 17:59:36 $
|
|
||||||
|
|
||||||
% Ensure that java awt is enabled...
|
|
||||||
if ~usejava('awt')
|
|
||||||
error('YMA:screencapture:NeedAwt','ScreenCapture requires Java to run.');
|
|
||||||
end
|
|
||||||
|
|
||||||
% Ensure that our Java version supports the Robot class (requires JVM 1.3+)
|
|
||||||
try
|
|
||||||
robot = java.awt.Robot; %#ok<NASGU>
|
|
||||||
catch
|
|
||||||
uiwait(msgbox({['Your Matlab installation is so old that its Java engine (' version('-java') ...
|
|
||||||
') does not have a java.awt.Robot class. '], ' ', ...
|
|
||||||
'Without this class, taking a screen-capture is impossible.', ' ', ...
|
|
||||||
'So, either install JVM 1.3 or higher, or use a newer Matlab release.'}, ...
|
|
||||||
'ScreenCapture', 'warn'));
|
|
||||||
if nargout, imageData = []; end
|
|
||||||
return;
|
|
||||||
end
|
|
||||||
|
|
||||||
% Process optional arguments
|
|
||||||
paramsStruct = processArgs(varargin{:});
|
|
||||||
|
|
||||||
% If toolbar button requested, add it and exit
|
|
||||||
if ~isempty(paramsStruct.toolbar)
|
|
||||||
|
|
||||||
% Add the toolbar button
|
|
||||||
addToolbarButton(paramsStruct);
|
|
||||||
|
|
||||||
% Return the figure to its pre-undocked state (when relevant)
|
|
||||||
redockFigureIfRelevant(paramsStruct);
|
|
||||||
|
|
||||||
% Exit immediately (do NOT take a screen-capture)
|
|
||||||
if nargout, imageData = []; end
|
|
||||||
return;
|
|
||||||
end
|
|
||||||
|
|
||||||
% Convert position from handle-relative to desktop Java-based pixels
|
|
||||||
[paramsStruct, msgStr] = convertPos(paramsStruct);
|
|
||||||
|
|
||||||
% Capture the requested screen rectangle using java.awt.Robot
|
|
||||||
imgData = getScreenCaptureImageData(paramsStruct.position);
|
|
||||||
|
|
||||||
% Return the figure to its pre-undocked state (when relevant)
|
|
||||||
redockFigureIfRelevant(paramsStruct);
|
|
||||||
|
|
||||||
% Save image data in file or clipboard, if specified
|
|
||||||
if ~isempty(paramsStruct.target)
|
|
||||||
if strcmpi(paramsStruct.target,'clipboard')
|
|
||||||
if ~isempty(imgData)
|
|
||||||
imclipboard(imgData);
|
|
||||||
else
|
|
||||||
msgbox('No image area selected - not copying image to clipboard','ScreenCapture','warn');
|
|
||||||
end
|
|
||||||
elseif strncmpi(paramsStruct.target,'print',5) % 'print' or 'printer'
|
|
||||||
if ~isempty(imgData)
|
|
||||||
hNewFig = figure('visible','off');
|
|
||||||
imshow(imgData);
|
|
||||||
print(hNewFig);
|
|
||||||
delete(hNewFig);
|
|
||||||
else
|
|
||||||
msgbox('No image area selected - not printing screenshot','ScreenCapture','warn');
|
|
||||||
end
|
|
||||||
else % real filename
|
|
||||||
if ~isempty(imgData)
|
|
||||||
imwrite(imgData,paramsStruct.target);
|
|
||||||
else
|
|
||||||
msgbox(['No image area selected - not saving image file ' paramsStruct.target],'ScreenCapture','warn');
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
% Return image raster data to user, if requested
|
|
||||||
if nargout
|
|
||||||
imageData = imgData;
|
|
||||||
|
|
||||||
% If neither output formats was specified (neither target nor output data)
|
|
||||||
elseif isempty(paramsStruct.target) & ~isempty(imgData) %#ok ML6
|
|
||||||
% Ask the user to specify a file
|
|
||||||
%error('YMA:screencapture:noOutput','No output specified for ScreenCapture: specify the output filename and/or output data');
|
|
||||||
%format = '*.*';
|
|
||||||
formats = imformats;
|
|
||||||
for idx = 1 : numel(formats)
|
|
||||||
ext = sprintf('*.%s;',formats(idx).ext{:});
|
|
||||||
format(idx,1:2) = {ext(1:end-1), formats(idx).description}; %#ok<AGROW>
|
|
||||||
end
|
|
||||||
[filename,pathname] = uiputfile(format,'Save screen capture as');
|
|
||||||
if ~isequal(filename,0) & ~isequal(pathname,0) %#ok Matlab6 compatibility
|
|
||||||
try
|
|
||||||
filename = fullfile(pathname,filename);
|
|
||||||
imwrite(imgData,filename);
|
|
||||||
catch % possibly a GIF file that requires indexed colors
|
|
||||||
[imgData,map] = rgb2ind(imgData,256);
|
|
||||||
imwrite(imgData,map,filename);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
% TODO - copy to clipboard
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
% Display msgStr, if relevant
|
|
||||||
if ~isempty(msgStr)
|
|
||||||
uiwait(msgbox(msgStr,'ScreenCapture'));
|
|
||||||
drawnow; pause(0.05); % time for the msgbox to disappear
|
|
||||||
end
|
|
||||||
|
|
||||||
return; % debug breakpoint
|
|
||||||
|
|
||||||
%% Process optional arguments
|
|
||||||
function paramsStruct = processArgs(varargin)
|
|
||||||
|
|
||||||
% Get the properties in either direct or P-V format
|
|
||||||
[regParams, pvPairs] = parseparams(varargin);
|
|
||||||
|
|
||||||
% Now process the optional P-V params
|
|
||||||
try
|
|
||||||
% Initialize
|
|
||||||
paramName = [];
|
|
||||||
paramsStruct = [];
|
|
||||||
paramsStruct.handle = [];
|
|
||||||
paramsStruct.position = [];
|
|
||||||
paramsStruct.target = '';
|
|
||||||
paramsStruct.toolbar = [];
|
|
||||||
paramsStruct.wasDocked = 0; % no false available in ML6
|
|
||||||
paramsStruct.wasInteractive = 0; % no false available in ML6
|
|
||||||
|
|
||||||
% Parse the regular (non-named) params in recption order
|
|
||||||
if ~isempty(regParams) & (isempty(regParams{1}) | ishandle(regParams{1}(1))) %#ok ML6
|
|
||||||
paramsStruct.handle = regParams{1};
|
|
||||||
regParams(1) = [];
|
|
||||||
end
|
|
||||||
if ~isempty(regParams) & isnumeric(regParams{1}) & (length(regParams{1}) == 4) %#ok ML6
|
|
||||||
paramsStruct.position = regParams{1};
|
|
||||||
regParams(1) = [];
|
|
||||||
end
|
|
||||||
if ~isempty(regParams) & ischar(regParams{1}) %#ok ML6
|
|
||||||
paramsStruct.target = regParams{1};
|
|
||||||
end
|
|
||||||
|
|
||||||
% Parse the optional param PV pairs
|
|
||||||
supportedArgs = {'handle','position','target','toolbar'};
|
|
||||||
while ~isempty(pvPairs)
|
|
||||||
|
|
||||||
% Disregard empty propNames (may be due to users mis-interpretting the syntax help)
|
|
||||||
while ~isempty(pvPairs) & isempty(pvPairs{1}) %#ok ML6
|
|
||||||
pvPairs(1) = [];
|
|
||||||
end
|
|
||||||
if isempty(pvPairs)
|
|
||||||
break;
|
|
||||||
end
|
|
||||||
|
|
||||||
% Ensure basic format is valid
|
|
||||||
paramName = '';
|
|
||||||
if ~ischar(pvPairs{1})
|
|
||||||
error('YMA:screencapture:invalidProperty','Invalid property passed to ScreenCapture');
|
|
||||||
elseif length(pvPairs) == 1
|
|
||||||
if isempty(paramsStruct.target)
|
|
||||||
paramsStruct.target = pvPairs{1};
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
error('YMA:screencapture:noPropertyValue',['No value specified for property ''' pvPairs{1} '''']);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
% Process parameter values
|
|
||||||
paramName = pvPairs{1};
|
|
||||||
if strcmpi(paramName,'filename') % backward compatibility
|
|
||||||
paramName = 'target';
|
|
||||||
end
|
|
||||||
paramValue = pvPairs{2};
|
|
||||||
pvPairs(1:2) = [];
|
|
||||||
idx = find(strncmpi(paramName,supportedArgs,length(paramName)));
|
|
||||||
if ~isempty(idx)
|
|
||||||
%paramsStruct.(lower(supportedArgs{idx(1)})) = paramValue; % incompatible with ML6
|
|
||||||
paramsStruct = setfield(paramsStruct, lower(supportedArgs{idx(1)}), paramValue); %#ok ML6
|
|
||||||
|
|
||||||
% If 'toolbar' param specified, then it cannot be left empty - use gcf
|
|
||||||
if strncmpi(paramName,'toolbar',length(paramName)) & isempty(paramsStruct.toolbar) %#ok ML6
|
|
||||||
paramsStruct.toolbar = getCurrentFig;
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif isempty(paramsStruct.target)
|
|
||||||
paramsStruct.target = paramName;
|
|
||||||
pvPairs = {paramValue, pvPairs{:}}; %#ok (more readable this way, although a bit less efficient...)
|
|
||||||
|
|
||||||
else
|
|
||||||
supportedArgsStr = sprintf('''%s'',',supportedArgs{:});
|
|
||||||
error('YMA:screencapture:invalidProperty','%s \n%s', ...
|
|
||||||
'Invalid property passed to ScreenCapture', ...
|
|
||||||
['Supported property names are: ' supportedArgsStr(1:end-1)]);
|
|
||||||
end
|
|
||||||
end % loop pvPairs
|
|
||||||
|
|
||||||
catch
|
|
||||||
if ~isempty(paramName), paramName = [' ''' paramName '''']; end
|
|
||||||
error('YMA:screencapture:invalidProperty','Error setting ScreenCapture property %s:\n%s',paramName,lasterr); %#ok<LERR>
|
|
||||||
end
|
|
||||||
%end % processArgs
|
|
||||||
|
|
||||||
%% Convert position from handle-relative to desktop Java-based pixels
|
|
||||||
function [paramsStruct, msgStr] = convertPos(paramsStruct)
|
|
||||||
msgStr = '';
|
|
||||||
try
|
|
||||||
% Get the screen-size for later use
|
|
||||||
screenSize = get(0,'ScreenSize');
|
|
||||||
|
|
||||||
% Get the containing figure's handle
|
|
||||||
hParent = paramsStruct.handle;
|
|
||||||
if isempty(paramsStruct.handle)
|
|
||||||
paramsStruct.hFigure = getCurrentFig;
|
|
||||||
hParent = paramsStruct.hFigure;
|
|
||||||
else
|
|
||||||
paramsStruct.hFigure = ancestor(paramsStruct.handle,'figure');
|
|
||||||
end
|
|
||||||
|
|
||||||
% To get the acurate pixel position, the figure window must be undocked
|
|
||||||
try
|
|
||||||
if strcmpi(get(paramsStruct.hFigure,'WindowStyle'),'docked')
|
|
||||||
set(paramsStruct.hFigure,'WindowStyle','normal');
|
|
||||||
drawnow; pause(0.25);
|
|
||||||
paramsStruct.wasDocked = 1; % no true available in ML6
|
|
||||||
end
|
|
||||||
catch
|
|
||||||
% never mind - ignore...
|
|
||||||
end
|
|
||||||
|
|
||||||
% The figure (if specified) must be in focus
|
|
||||||
if ~isempty(paramsStruct.hFigure) & ishandle(paramsStruct.hFigure) %#ok ML6
|
|
||||||
isFigureValid = 1; % no true available in ML6
|
|
||||||
figure(paramsStruct.hFigure);
|
|
||||||
else
|
|
||||||
isFigureValid = 0; % no false available in ML6
|
|
||||||
end
|
|
||||||
|
|
||||||
% Flush all graphic events to ensure correct rendering
|
|
||||||
drawnow; pause(0.01);
|
|
||||||
|
|
||||||
% No handle specified
|
|
||||||
wasPositionGiven = 1; % no true available in ML6
|
|
||||||
if isempty(paramsStruct.handle)
|
|
||||||
|
|
||||||
% Set default handle, if not supplied
|
|
||||||
paramsStruct.handle = paramsStruct.hFigure;
|
|
||||||
|
|
||||||
% If position was not specified, get it interactively using RBBOX
|
|
||||||
if isempty(paramsStruct.position)
|
|
||||||
[paramsStruct.position, jFrameUsed, msgStr] = getInteractivePosition(paramsStruct.hFigure); %#ok<ASGLU> jFrameUsed is unused
|
|
||||||
paramsStruct.wasInteractive = 1; % no true available in ML6
|
|
||||||
wasPositionGiven = 0; % no false available in ML6
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif ~ishandle(paramsStruct.handle)
|
|
||||||
% Handle was supplied - ensure it is a valid handle
|
|
||||||
error('YMA:screencapture:invalidHandle','Invalid handle passed to ScreenCapture');
|
|
||||||
|
|
||||||
elseif isempty(paramsStruct.position)
|
|
||||||
% Handle was supplied but position was not, so use the handle's position
|
|
||||||
paramsStruct.position = getPixelPos(paramsStruct.handle);
|
|
||||||
paramsStruct.position(1:2) = 0;
|
|
||||||
wasPositionGiven = 0; % no false available in ML6
|
|
||||||
|
|
||||||
elseif ~isnumeric(paramsStruct.position) | (length(paramsStruct.position) ~= 4) %#ok ML6
|
|
||||||
% Both handle & position were supplied - ensure a valid pixel position vector
|
|
||||||
error('YMA:screencapture:invalidPosition','Invalid position vector passed to ScreenCapture: \nMust be a [x,y,w,h] numeric pixel array');
|
|
||||||
end
|
|
||||||
|
|
||||||
% Capture current object (uicontrol/axes/figure) if w=h=0 (single-click in interactive mode)
|
|
||||||
if paramsStruct.position(3)<=0 | paramsStruct.position(4)<=0 %#ok ML6
|
|
||||||
%TODO - find a way to single-click another Matlab figure (the following does not work)
|
|
||||||
%paramsStruct.position = getPixelPos(ancestor(hittest,'figure'));
|
|
||||||
paramsStruct.position = getPixelPos(paramsStruct.handle);
|
|
||||||
paramsStruct.position(1:2) = 0;
|
|
||||||
paramsStruct.wasInteractive = 0; % no false available in ML6
|
|
||||||
wasPositionGiven = 0; % no false available in ML6
|
|
||||||
end
|
|
||||||
|
|
||||||
% First get the parent handle's desktop-based Matlab pixel position
|
|
||||||
parentPos = [0,0,0,0];
|
|
||||||
dX = 0;
|
|
||||||
dY = 0;
|
|
||||||
dW = 0;
|
|
||||||
dH = 0;
|
|
||||||
if ~isFigure(hParent)
|
|
||||||
% Get the reguested component's pixel position
|
|
||||||
parentPos = getPixelPos(hParent, 1); % no true available in ML6
|
|
||||||
|
|
||||||
% Axes position inaccuracy estimation
|
|
||||||
deltaX = 3;
|
|
||||||
deltaY = -1;
|
|
||||||
|
|
||||||
% Fix for images
|
|
||||||
if isImage(hParent) % | (isAxes(hParent) & strcmpi(get(hParent,'YDir'),'reverse')) %#ok ML6
|
|
||||||
|
|
||||||
% Compensate for resized image axes
|
|
||||||
hAxes = get(hParent,'Parent');
|
|
||||||
if all(get(hAxes,'DataAspectRatio')==1) % sanity check: this is the normal behavior
|
|
||||||
% Note 18/4/2013: the following fails for non-square images
|
|
||||||
%actualImgSize = min(parentPos(3:4));
|
|
||||||
%dX = (parentPos(3) - actualImgSize) / 2;
|
|
||||||
%dY = (parentPos(4) - actualImgSize) / 2;
|
|
||||||
%parentPos(3:4) = actualImgSize;
|
|
||||||
|
|
||||||
% The following should work for all types of images
|
|
||||||
actualImgSize = size(get(hParent,'CData'));
|
|
||||||
dX = (parentPos(3) - min(parentPos(3),actualImgSize(2))) / 2;
|
|
||||||
dY = (parentPos(4) - min(parentPos(4),actualImgSize(1))) / 2;
|
|
||||||
parentPos(3:4) = actualImgSize([2,1]);
|
|
||||||
%parentPos(3) = max(parentPos(3),actualImgSize(2));
|
|
||||||
%parentPos(4) = max(parentPos(4),actualImgSize(1));
|
|
||||||
end
|
|
||||||
|
|
||||||
% Fix user-specified img positions (but not auto-inferred ones)
|
|
||||||
if wasPositionGiven
|
|
||||||
|
|
||||||
% In images, use data units rather than pixel units
|
|
||||||
% Reverse the YDir
|
|
||||||
ymax = max(get(hParent,'YData'));
|
|
||||||
paramsStruct.position(2) = ymax - paramsStruct.position(2) - paramsStruct.position(4);
|
|
||||||
|
|
||||||
% Note: it would be best to use hgconvertunits, but:
|
|
||||||
% ^^^^ (1) it fails on Matlab 6, and (2) it doesn't accept Data units
|
|
||||||
%paramsStruct.position = hgconvertunits(hFig, paramsStruct.position, 'Data', 'pixel', hParent); % fails!
|
|
||||||
xLims = get(hParent,'XData');
|
|
||||||
yLims = get(hParent,'YData');
|
|
||||||
xPixelsPerData = parentPos(3) / (diff(xLims) + 1);
|
|
||||||
yPixelsPerData = parentPos(4) / (diff(yLims) + 1);
|
|
||||||
paramsStruct.position(1) = round((paramsStruct.position(1)-xLims(1)) * xPixelsPerData);
|
|
||||||
paramsStruct.position(2) = round((paramsStruct.position(2)-yLims(1)) * yPixelsPerData + 2*dY);
|
|
||||||
paramsStruct.position(3) = round( paramsStruct.position(3) * xPixelsPerData);
|
|
||||||
paramsStruct.position(4) = round( paramsStruct.position(4) * yPixelsPerData);
|
|
||||||
|
|
||||||
% Axes position inaccuracy estimation
|
|
||||||
if strcmpi(computer('arch'),'win64')
|
|
||||||
deltaX = 7;
|
|
||||||
deltaY = -7;
|
|
||||||
else
|
|
||||||
deltaX = 3;
|
|
||||||
deltaY = -3;
|
|
||||||
end
|
|
||||||
|
|
||||||
else % axes/image position was auto-infered (entire image)
|
|
||||||
% Axes position inaccuracy estimation
|
|
||||||
if strcmpi(computer('arch'),'win64')
|
|
||||||
deltaX = 6;
|
|
||||||
deltaY = -6;
|
|
||||||
else
|
|
||||||
deltaX = 2;
|
|
||||||
deltaY = -2;
|
|
||||||
end
|
|
||||||
dW = -2*dX;
|
|
||||||
dH = -2*dY;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
%hFig = ancestor(hParent,'figure');
|
|
||||||
hParent = paramsStruct.hFigure;
|
|
||||||
|
|
||||||
elseif paramsStruct.wasInteractive % interactive figure rectangle
|
|
||||||
|
|
||||||
% Compensate for 1px rbbox inaccuracies
|
|
||||||
deltaX = 2;
|
|
||||||
deltaY = -2;
|
|
||||||
|
|
||||||
else % non-interactive figure
|
|
||||||
|
|
||||||
% Compensate 4px figure boundaries = difference betweeen OuterPosition and Position
|
|
||||||
deltaX = -1;
|
|
||||||
deltaY = 1;
|
|
||||||
end
|
|
||||||
%disp(paramsStruct.position) % for debugging
|
|
||||||
|
|
||||||
% Now get the pixel position relative to the monitor
|
|
||||||
figurePos = getPixelPos(hParent);
|
|
||||||
desktopPos = figurePos + parentPos;
|
|
||||||
|
|
||||||
% Now convert to Java-based pixels based on screen size
|
|
||||||
% Note: multiple monitors are automatically handled correctly, since all
|
|
||||||
% ^^^^ Java positions are relative to the main monitor's top-left corner
|
|
||||||
javaX = desktopPos(1) + paramsStruct.position(1) + deltaX + dX;
|
|
||||||
javaY = screenSize(4) - desktopPos(2) - paramsStruct.position(2) - paramsStruct.position(4) + deltaY + dY;
|
|
||||||
width = paramsStruct.position(3) + dW;
|
|
||||||
height = paramsStruct.position(4) + dH;
|
|
||||||
paramsStruct.position = round([javaX, javaY, width, height]);
|
|
||||||
%paramsStruct.position
|
|
||||||
|
|
||||||
% Ensure the figure is at the front so it can be screen-captured
|
|
||||||
if isFigureValid
|
|
||||||
figure(hParent);
|
|
||||||
drawnow;
|
|
||||||
pause(0.02);
|
|
||||||
end
|
|
||||||
catch
|
|
||||||
% Maybe root/desktop handle (root does not have a 'Position' prop so getPixelPos croaks
|
|
||||||
if isequal(double(hParent),0) % =root/desktop handle; handles case of hParent=[]
|
|
||||||
javaX = paramsStruct.position(1) - 1;
|
|
||||||
javaY = screenSize(4) - paramsStruct.position(2) - paramsStruct.position(4) - 1;
|
|
||||||
paramsStruct.position = [javaX, javaY, paramsStruct.position(3:4)];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
%end % convertPos
|
|
||||||
|
|
||||||
%% Interactively get the requested capture rectangle
|
|
||||||
function [positionRect, jFrameUsed, msgStr] = getInteractivePosition(hFig)
|
|
||||||
msgStr = '';
|
|
||||||
try
|
|
||||||
% First try the invisible-figure approach, in order to
|
|
||||||
% enable rbbox outside any existing figure boundaries
|
|
||||||
f = figure('units','pixel','pos',[-100,-100,10,10],'HitTest','off');
|
|
||||||
drawnow; pause(0.01);
|
|
||||||
oldWarn = warning('off','MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame');
|
|
||||||
jf = get(handle(f),'JavaFrame');
|
|
||||||
warning(oldWarn);
|
|
||||||
try
|
|
||||||
jWindow = jf.fFigureClient.getWindow;
|
|
||||||
catch
|
|
||||||
try
|
|
||||||
jWindow = jf.fHG1Client.getWindow;
|
|
||||||
catch
|
|
||||||
jWindow = jf.getFigurePanelContainer.getParent.getTopLevelAncestor;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
com.sun.awt.AWTUtilities.setWindowOpacity(jWindow,0.05); %=nearly transparent (not fully so that mouse clicks are captured)
|
|
||||||
jWindow.setMaximized(1); % no true available in ML6
|
|
||||||
jFrameUsed = 1; % no true available in ML6
|
|
||||||
msg = {'Mouse-click and drag a bounding rectangle for screen-capture ' ...
|
|
||||||
... %'or single-click any Matlab figure to capture the entire figure.' ...
|
|
||||||
};
|
|
||||||
catch
|
|
||||||
% Something failed, so revert to a simple rbbox on a visible figure
|
|
||||||
try delete(f); drawnow; catch, end %Cleanup...
|
|
||||||
jFrameUsed = 0; % no false available in ML6
|
|
||||||
msg = {'Mouse-click within any Matlab figure and then', ...
|
|
||||||
'drag a bounding rectangle for screen-capture,', ...
|
|
||||||
'or single-click to capture the entire figure'};
|
|
||||||
end
|
|
||||||
uiwait(msgbox(msg,'ScreenCapture'));
|
|
||||||
|
|
||||||
k = waitforbuttonpress; %#ok k is unused
|
|
||||||
%hFig = getCurrentFig;
|
|
||||||
%p1 = get(hFig,'CurrentPoint');
|
|
||||||
positionRect = rbbox;
|
|
||||||
%p2 = get(hFig,'CurrentPoint');
|
|
||||||
|
|
||||||
if jFrameUsed
|
|
||||||
jFrameOrigin = getPixelPos(f);
|
|
||||||
delete(f); drawnow;
|
|
||||||
try
|
|
||||||
figOrigin = getPixelPos(hFig);
|
|
||||||
catch % empty/invalid hFig handle
|
|
||||||
figOrigin = [0,0,0,0];
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if isempty(hFig)
|
|
||||||
jFrameOrigin = getPixelPos(gcf);
|
|
||||||
else
|
|
||||||
jFrameOrigin = [0,0,0,0];
|
|
||||||
end
|
|
||||||
figOrigin = [0,0,0,0];
|
|
||||||
end
|
|
||||||
positionRect(1:2) = positionRect(1:2) + jFrameOrigin(1:2) - figOrigin(1:2);
|
|
||||||
|
|
||||||
if prod(positionRect(3:4)) > 0
|
|
||||||
msgStr = sprintf('%dx%d area captured',positionRect(3),positionRect(4));
|
|
||||||
end
|
|
||||||
%end % getInteractivePosition
|
|
||||||
|
|
||||||
%% Get current figure (even if its handle is hidden)
|
|
||||||
function hFig = getCurrentFig
|
|
||||||
oldState = get(0,'showHiddenHandles');
|
|
||||||
set(0,'showHiddenHandles','on');
|
|
||||||
hFig = get(0,'CurrentFigure');
|
|
||||||
set(0,'showHiddenHandles',oldState);
|
|
||||||
%end % getCurrentFig
|
|
||||||
|
|
||||||
%% Get ancestor figure - used for old Matlab versions that don't have a built-in ancestor()
|
|
||||||
function hObj = ancestor(hObj,type)
|
|
||||||
if ~isempty(hObj) & ishandle(hObj) %#ok for Matlab 6 compatibility
|
|
||||||
try
|
|
||||||
hObj = get(hObj,'Ancestor');
|
|
||||||
catch
|
|
||||||
% never mind...
|
|
||||||
end
|
|
||||||
try
|
|
||||||
%if ~isa(handle(hObj),type) % this is best but always returns 0 in Matlab 6!
|
|
||||||
%if ~isprop(hObj,'type') | ~strcmpi(get(hObj,'type'),type) % no isprop() in ML6!
|
|
||||||
try
|
|
||||||
objType = get(hObj,'type');
|
|
||||||
catch
|
|
||||||
objType = '';
|
|
||||||
end
|
|
||||||
if ~strcmpi(objType,type)
|
|
||||||
try
|
|
||||||
parent = get(handle(hObj),'parent');
|
|
||||||
catch
|
|
||||||
parent = hObj.getParent; % some objs have no 'Parent' prop, just this method...
|
|
||||||
end
|
|
||||||
if ~isempty(parent) % empty parent means root ancestor, so exit
|
|
||||||
hObj = ancestor(parent,type);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
catch
|
|
||||||
% never mind...
|
|
||||||
end
|
|
||||||
end
|
|
||||||
%end % ancestor
|
|
||||||
|
|
||||||
%% Get position of an HG object in specified units
|
|
||||||
function pos = getPos(hObj,field,units)
|
|
||||||
% Matlab 6 did not have hgconvertunits so use the old way...
|
|
||||||
oldUnits = get(hObj,'units');
|
|
||||||
if strcmpi(oldUnits,units) % don't modify units unless we must!
|
|
||||||
pos = get(hObj,field);
|
|
||||||
else
|
|
||||||
set(hObj,'units',units);
|
|
||||||
pos = get(hObj,field);
|
|
||||||
set(hObj,'units',oldUnits);
|
|
||||||
end
|
|
||||||
%end % getPos
|
|
||||||
|
|
||||||
%% Get pixel position of an HG object - for Matlab 6 compatibility
|
|
||||||
function pos = getPixelPos(hObj,varargin)
|
|
||||||
persistent originalObj
|
|
||||||
try
|
|
||||||
stk = dbstack;
|
|
||||||
if ~strcmp(stk(2).name,'getPixelPos')
|
|
||||||
originalObj = hObj;
|
|
||||||
end
|
|
||||||
|
|
||||||
if isFigure(hObj) %| isAxes(hObj)
|
|
||||||
%try
|
|
||||||
pos = getPos(hObj,'OuterPosition','pixels');
|
|
||||||
else %catch
|
|
||||||
% getpixelposition is unvectorized unfortunately!
|
|
||||||
pos = getpixelposition(hObj,varargin{:});
|
|
||||||
|
|
||||||
% add the axes labels/ticks if relevant (plus a tiny margin to fix 2px label/title inconsistencies)
|
|
||||||
if isAxes(hObj) & ~isImage(originalObj) %#ok ML6
|
|
||||||
tightInsets = getPos(hObj,'TightInset','pixel');
|
|
||||||
pos = pos + tightInsets.*[-1,-1,1,1] + [-1,1,1+tightInsets(1:2)];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
catch
|
|
||||||
try
|
|
||||||
% Matlab 6 did not have getpixelposition nor hgconvertunits so use the old way...
|
|
||||||
pos = getPos(hObj,'Position','pixels');
|
|
||||||
catch
|
|
||||||
% Maybe the handle does not have a 'Position' prop (e.g., text/line/plot) - use its parent
|
|
||||||
pos = getPixelPos(get(hObj,'parent'),varargin{:});
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
% Handle the case of missing/invalid/empty HG handle
|
|
||||||
if isempty(pos)
|
|
||||||
pos = [0,0,0,0];
|
|
||||||
end
|
|
||||||
%end % getPixelPos
|
|
||||||
|
|
||||||
%% Adds a ScreenCapture toolbar button
|
|
||||||
function addToolbarButton(paramsStruct)
|
|
||||||
% Ensure we have a valid toolbar handle
|
|
||||||
hFig = ancestor(paramsStruct.toolbar,'figure');
|
|
||||||
if isempty(hFig)
|
|
||||||
error('YMA:screencapture:badToolbar','the ''Toolbar'' parameter must contain a valid GUI handle');
|
|
||||||
end
|
|
||||||
set(hFig,'ToolBar','figure');
|
|
||||||
hToolbar = findall(hFig,'type','uitoolbar');
|
|
||||||
if isempty(hToolbar)
|
|
||||||
error('YMA:screencapture:noToolbar','the ''Toolbar'' parameter must contain a figure handle possessing a valid toolbar');
|
|
||||||
end
|
|
||||||
hToolbar = hToolbar(1); % just in case there are several toolbars... - use only the first
|
|
||||||
|
|
||||||
% Prepare the camera icon
|
|
||||||
icon = ['3333333333333333'; ...
|
|
||||||
'3333333333333333'; ...
|
|
||||||
'3333300000333333'; ...
|
|
||||||
'3333065556033333'; ...
|
|
||||||
'3000000000000033'; ...
|
|
||||||
'3022222222222033'; ...
|
|
||||||
'3022220002222033'; ...
|
|
||||||
'3022203110222033'; ...
|
|
||||||
'3022201110222033'; ...
|
|
||||||
'3022204440222033'; ...
|
|
||||||
'3022220002222033'; ...
|
|
||||||
'3022222222222033'; ...
|
|
||||||
'3000000000000033'; ...
|
|
||||||
'3333333333333333'; ...
|
|
||||||
'3333333333333333'; ...
|
|
||||||
'3333333333333333'];
|
|
||||||
cm = [ 0 0 0; ... % black
|
|
||||||
0 0.60 1; ... % light blue
|
|
||||||
0.53 0.53 0.53; ... % light gray
|
|
||||||
NaN NaN NaN; ... % transparent
|
|
||||||
0 0.73 0; ... % light green
|
|
||||||
0.27 0.27 0.27; ... % gray
|
|
||||||
0.13 0.13 0.13]; % dark gray
|
|
||||||
cdata = ind2rgb(uint8(icon-'0'),cm);
|
|
||||||
|
|
||||||
% If the button does not already exit
|
|
||||||
hButton = findall(hToolbar,'Tag','ScreenCaptureButton');
|
|
||||||
tooltip = 'Screen capture';
|
|
||||||
if ~isempty(paramsStruct.target)
|
|
||||||
tooltip = [tooltip ' to ' paramsStruct.target];
|
|
||||||
end
|
|
||||||
if isempty(hButton)
|
|
||||||
% Add the button with the icon to the figure's toolbar
|
|
||||||
hButton = uipushtool(hToolbar, 'CData',cdata, 'Tag','ScreenCaptureButton', 'TooltipString',tooltip, 'ClickedCallback',['screencapture(''' paramsStruct.target ''')']); %#ok unused
|
|
||||||
else
|
|
||||||
% Otherwise, simply update the existing button
|
|
||||||
set(hButton, 'CData',cdata, 'Tag','ScreenCaptureButton', 'TooltipString',tooltip, 'ClickedCallback',['screencapture(''' paramsStruct.target ''')']);
|
|
||||||
end
|
|
||||||
%end % addToolbarButton
|
|
||||||
|
|
||||||
%% Java-get the actual screen-capture image data
|
|
||||||
function imgData = getScreenCaptureImageData(positionRect)
|
|
||||||
if isempty(positionRect) | all(positionRect==0) | positionRect(3)<=0 | positionRect(4)<=0 %#ok ML6
|
|
||||||
imgData = [];
|
|
||||||
else
|
|
||||||
% Use java.awt.Robot to take a screen-capture of the specified screen area
|
|
||||||
rect = java.awt.Rectangle(positionRect(1), positionRect(2), positionRect(3), positionRect(4));
|
|
||||||
robot = java.awt.Robot;
|
|
||||||
jImage = robot.createScreenCapture(rect);
|
|
||||||
|
|
||||||
% Convert the resulting Java image to a Matlab image
|
|
||||||
% Adapted for a much-improved performance from:
|
|
||||||
% http://www.mathworks.com/support/solutions/data/1-2WPAYR.html
|
|
||||||
h = jImage.getHeight;
|
|
||||||
w = jImage.getWidth;
|
|
||||||
%imgData = zeros([h,w,3],'uint8');
|
|
||||||
%pixelsData = uint8(jImage.getData.getPixels(0,0,w,h,[]));
|
|
||||||
%for i = 1 : h
|
|
||||||
% base = (i-1)*w*3+1;
|
|
||||||
% imgData(i,1:w,:) = deal(reshape(pixelsData(base:(base+3*w-1)),3,w)');
|
|
||||||
%end
|
|
||||||
|
|
||||||
% Performance further improved based on feedback from Urs Schwartz:
|
|
||||||
%pixelsData = reshape(typecast(jImage.getData.getDataStorage,'uint32'),w,h).';
|
|
||||||
%imgData(:,:,3) = bitshift(bitand(pixelsData,256^1-1),-8*0);
|
|
||||||
%imgData(:,:,2) = bitshift(bitand(pixelsData,256^2-1),-8*1);
|
|
||||||
%imgData(:,:,1) = bitshift(bitand(pixelsData,256^3-1),-8*2);
|
|
||||||
|
|
||||||
% Performance even further improved based on feedback from Jan Simon:
|
|
||||||
pixelsData = reshape(typecast(jImage.getData.getDataStorage, 'uint8'), 4, w, h);
|
|
||||||
imgData = cat(3, ...
|
|
||||||
transpose(reshape(pixelsData(3, :, :), w, h)), ...
|
|
||||||
transpose(reshape(pixelsData(2, :, :), w, h)), ...
|
|
||||||
transpose(reshape(pixelsData(1, :, :), w, h)));
|
|
||||||
end
|
|
||||||
%end % getInteractivePosition
|
|
||||||
|
|
||||||
%% Return the figure to its pre-undocked state (when relevant)
|
|
||||||
function redockFigureIfRelevant(paramsStruct)
|
|
||||||
if paramsStruct.wasDocked
|
|
||||||
try
|
|
||||||
set(paramsStruct.hFigure,'WindowStyle','docked');
|
|
||||||
%drawnow;
|
|
||||||
catch
|
|
||||||
% never mind - ignore...
|
|
||||||
end
|
|
||||||
end
|
|
||||||
%end % redockFigureIfRelevant
|
|
||||||
|
|
||||||
%% Copy screen-capture to the system clipboard
|
|
||||||
% Adapted from http://www.mathworks.com/matlabcentral/fileexchange/28708-imclipboard/content/imclipboard.m
|
|
||||||
function imclipboard(imgData)
|
|
||||||
% Import necessary Java classes
|
|
||||||
import java.awt.Toolkit.*
|
|
||||||
import java.awt.image.BufferedImage
|
|
||||||
import java.awt.datatransfer.DataFlavor
|
|
||||||
|
|
||||||
% Add the necessary Java class (ImageSelection) to the Java classpath
|
|
||||||
if ~exist('ImageSelection', 'class')
|
|
||||||
% Obtain the directory of the executable (or of the M-file if not deployed)
|
|
||||||
%javaaddpath(fileparts(which(mfilename)), '-end');
|
|
||||||
if isdeployed % Stand-alone mode.
|
|
||||||
[status, result] = system('path'); %#ok<ASGLU>
|
|
||||||
MatLabFilePath = char(regexpi(result, 'Path=(.*?);', 'tokens', 'once'));
|
|
||||||
else % MATLAB mode.
|
|
||||||
MatLabFilePath = fileparts(mfilename('fullpath'));
|
|
||||||
end
|
|
||||||
javaaddpath(MatLabFilePath, '-end');
|
|
||||||
end
|
|
||||||
|
|
||||||
% Get System Clipboard object (java.awt.Toolkit)
|
|
||||||
cb = getDefaultToolkit.getSystemClipboard; % can't use () in ML6!
|
|
||||||
|
|
||||||
% Get image size
|
|
||||||
ht = size(imgData, 1);
|
|
||||||
wd = size(imgData, 2);
|
|
||||||
|
|
||||||
% Convert to Blue-Green-Red format
|
|
||||||
imgData = imgData(:, :, [3 2 1]);
|
|
||||||
|
|
||||||
% Convert to 3xWxH format
|
|
||||||
imgData = permute(imgData, [3, 2, 1]);
|
|
||||||
|
|
||||||
% Append Alpha data (not used)
|
|
||||||
imgData = cat(1, imgData, 255*ones(1, wd, ht, 'uint8'));
|
|
||||||
|
|
||||||
% Create image buffer
|
|
||||||
imBuffer = BufferedImage(wd, ht, BufferedImage.TYPE_INT_RGB);
|
|
||||||
imBuffer.setRGB(0, 0, wd, ht, typecast(imgData(:), 'int32'), 0, wd);
|
|
||||||
|
|
||||||
% Create ImageSelection object
|
|
||||||
% % custom java class
|
|
||||||
imSelection = ImageSelection(imBuffer);
|
|
||||||
|
|
||||||
% Set clipboard content to the image
|
|
||||||
cb.setContents(imSelection, []);
|
|
||||||
%end %imclipboard
|
|
||||||
|
|
||||||
%% Is the provided handle a figure?
|
|
||||||
function flag = isFigure(hObj)
|
|
||||||
flag = isa(handle(hObj),'figure') | isa(hObj,'matlab.ui.Figure');
|
|
||||||
%end %isFigure
|
|
||||||
|
|
||||||
%% Is the provided handle an axes?
|
|
||||||
function flag = isAxes(hObj)
|
|
||||||
flag = isa(handle(hObj),'axes') | isa(hObj,'matlab.graphics.axis.Axes');
|
|
||||||
%end %isFigure
|
|
||||||
|
|
||||||
%% Is the provided handle an image?
|
|
||||||
function flag = isImage(hObj)
|
|
||||||
flag = isa(handle(hObj),'image') | isa(hObj,'matlab.graphics.primitive.Image');
|
|
||||||
%end %isFigure
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%% TODO %%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
% find a way in interactive-mode to single-click another Matlab figure for screen-capture
|
|
@ -1,73 +0,0 @@
|
|||||||
function plotAngularDistributionForDifferentBeta(obj, Beta)
|
|
||||||
|
|
||||||
f_h = Helper.getFigureByTag('AngDistForBeta');
|
|
||||||
set(groot,'CurrentFigure',f_h);
|
|
||||||
a_h = get(f_h, 'CurrentAxes');
|
|
||||||
if ~isempty(get(a_h, 'Children'))
|
|
||||||
clf(f_h);
|
|
||||||
end
|
|
||||||
f_h.Name = 'Beta dependence';
|
|
||||||
f_h.Units = 'pixels';
|
|
||||||
|
|
||||||
set(0,'units','pixels');
|
|
||||||
screensize = get(0,'ScreenSize');
|
|
||||||
f_h.Position = [[screensize(3)/3.5 screensize(4)/3.5] 750 600];
|
|
||||||
|
|
||||||
hold on
|
|
||||||
|
|
||||||
SimulationBeta = obj.Beta;
|
|
||||||
|
|
||||||
if ~ismember(SimulationBeta, Beta)
|
|
||||||
theta = linspace(0.0001,pi/2,1000);
|
|
||||||
J = zeros(1,length(theta));
|
|
||||||
for j=1:length(theta)
|
|
||||||
J(j) = obj.angularDistributionFunction(theta(j));
|
|
||||||
end
|
|
||||||
Norm = 0;
|
|
||||||
for j=1:length(J)
|
|
||||||
Norm = Norm+J(j)*sin(theta(j))*(theta(2)-theta(1));
|
|
||||||
end
|
|
||||||
J = J ./Norm*2;
|
|
||||||
J = J ./max(J);
|
|
||||||
plot([-flip(theta),theta], [flip(J),J],'DisplayName', ['\beta = ',num2str(SimulationBeta, '%.3f')], 'Linewidth',1.5)
|
|
||||||
end
|
|
||||||
|
|
||||||
for i=1:length(Beta)
|
|
||||||
|
|
||||||
theta = linspace(0.0001,pi/2,1000);
|
|
||||||
J = zeros(1,length(theta));
|
|
||||||
obj.NozzleLength = (2 * obj.NozzleRadius) / Beta(i);
|
|
||||||
|
|
||||||
for j=1:length(theta)
|
|
||||||
J(j) = obj.angularDistributionFunction(theta(j));
|
|
||||||
end
|
|
||||||
|
|
||||||
Norm = 0;
|
|
||||||
for j=1:length(J)
|
|
||||||
Norm = Norm+J(j)*sin(theta(j))*(theta(2)-theta(1));
|
|
||||||
end
|
|
||||||
J = J ./Norm*2;
|
|
||||||
J = J ./max(J);
|
|
||||||
|
|
||||||
if Beta(i) ~= SimulationBeta
|
|
||||||
plot([-flip(theta),theta], [flip(J),J],'DisplayName',['\beta = ',num2str(Beta(i))], 'LineStyle', '--', 'Linewidth',1.5)
|
|
||||||
else
|
|
||||||
plot([-flip(theta),theta], [flip(J),J],'DisplayName',['\beta = ',num2str(Beta(i))], 'Linewidth',1.5)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
hold off
|
|
||||||
|
|
||||||
leg = legend;
|
|
||||||
hXLabel = xlabel('\theta (rad)');
|
|
||||||
hYLabel = ylabel('J(\theta)');
|
|
||||||
hTitle = sgtitle('Angular Distribution (Transition Flow)');
|
|
||||||
|
|
||||||
set([hXLabel, hYLabel, leg] , ...
|
|
||||||
'FontSize' , 14 );
|
|
||||||
set( hTitle , ...
|
|
||||||
'FontSize' , 18 );
|
|
||||||
|
|
||||||
grid on
|
|
||||||
Helper.bringFiguresWithTagInForeground();
|
|
||||||
end
|
|
@ -1,37 +0,0 @@
|
|||||||
function plotCaptureVelocityVsAngle(OvenObj, MOTObj)
|
|
||||||
|
|
||||||
theta = linspace(0, OvenObj.ExitDivergence, 1000);
|
|
||||||
CaptureVelocity = zeros(length(theta),3);
|
|
||||||
|
|
||||||
for i=1:length(theta)
|
|
||||||
CaptureVelocity(i,:) = MOTObj.calculateCaptureVelocity(OvenObj, [-OvenObj.OvenDistance,0,0], [cos(theta(i)),0,sin(theta(i))]);
|
|
||||||
end
|
|
||||||
|
|
||||||
f_h = Helper.getFigureByTag('Capture Velocity');
|
|
||||||
set(groot,'CurrentFigure',f_h);
|
|
||||||
a_h = get(f_h, 'CurrentAxes');
|
|
||||||
if ~isempty(get(a_h, 'Children'))
|
|
||||||
clf(f_h);
|
|
||||||
end
|
|
||||||
f_h.Name = 'Capture Velocity';
|
|
||||||
f_h.Units = 'pixels';
|
|
||||||
|
|
||||||
set(0,'units','pixels');
|
|
||||||
screensize = get(0,'ScreenSize');
|
|
||||||
f_h.Position = [[screensize(3)/3.5 screensize(4)/3.5] 750 600];
|
|
||||||
|
|
||||||
plot(theta .* 1e+03, sqrt(CaptureVelocity(:,1).^2+CaptureVelocity(:,2).^2+CaptureVelocity(:,3).^2), 'Linewidth', 1.5)
|
|
||||||
|
|
||||||
hXLabel = xlabel('\theta (mrad)');
|
|
||||||
hYLabel = ylabel('Velocity (m/s)');
|
|
||||||
hTitle = sgtitle('Capture velocity for different angles of divergence');
|
|
||||||
|
|
||||||
set([hXLabel, hYLabel] , ...
|
|
||||||
'FontSize' , 14 );
|
|
||||||
set( hTitle , ...
|
|
||||||
'FontSize' , 14 );
|
|
||||||
|
|
||||||
grid on
|
|
||||||
Helper.bringFiguresWithTagInForeground();
|
|
||||||
|
|
||||||
end
|
|
@ -1,18 +0,0 @@
|
|||||||
function plotConfidenceIntervalRegion(x, y1, y2)
|
|
||||||
% draws two lines on a plot and shades the area between those
|
|
||||||
% lines to indicate confidence interval.
|
|
||||||
hold on
|
|
||||||
|
|
||||||
X_interpolated = linspace(min(x), max(x), 100);
|
|
||||||
Y1_interpolated = interp1(x,y1,X_interpolated);
|
|
||||||
Y2_interpolated = interp1(x,y2,X_interpolated);
|
|
||||||
|
|
||||||
%Plot the line edges
|
|
||||||
%plot(X_interpolated, Y1_interpolated, 'LineWidth', 0.5, 'LineStyle', '--', 'Color', '#FE1A1A');
|
|
||||||
%plot(X_interpolated, Y2_interpolated, 'LineWidth', 0.5, 'LineStyle', '--', 'Color', '#FE1A1A');
|
|
||||||
|
|
||||||
fill([X_interpolated fliplr(X_interpolated)], [Y1_interpolated fliplr(Y2_interpolated)], [0 71 138] ./ 255, 'EdgeColor', 'none', 'FaceAlpha', 0.2);
|
|
||||||
|
|
||||||
hold off
|
|
||||||
end
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
|||||||
function plotDynamicalQuantities(OvenObj, MOTObj, MaximumVelocity, IncidentAtomDirection, IncidentAtomPosition, varargin)
|
|
||||||
|
|
||||||
p = inputParser;
|
|
||||||
p.KeepUnmatched = true;
|
|
||||||
|
|
||||||
addRequired(p, 'OvenObject' , @isobject);
|
|
||||||
addRequired(p, 'MOTObject' , @isobject);
|
|
||||||
addRequired(p, 'MaximumVelocity' , @(x) assert(isnumeric(x) && isscalar(x)));
|
|
||||||
addRequired(p, 'IncidentAtomDirection' , @(x) assert(isnumeric(x) && isscalar(x)));
|
|
||||||
addRequired(p, 'IncidentAtomPosition' , @(x) assert(isnumeric(x) && isscalar(x)));
|
|
||||||
addParameter(p, 'PlotPositions' , false, @islogical);
|
|
||||||
addParameter(p, 'PlotVelocities' , false, @islogical);
|
|
||||||
|
|
||||||
p.parse(OvenObj, MOTObj, MaximumVelocity, IncidentAtomDirection, IncidentAtomPosition, varargin{:})
|
|
||||||
|
|
||||||
MaximumVelocity = p.Results.MaximumVelocity;
|
|
||||||
IncidentAtomDirection = p.Results.IncidentAtomDirection;
|
|
||||||
IncidentAtomPosition = p.Results.IncidentAtomDirection;
|
|
||||||
PlotPositions = p.Results.PlotPositions;
|
|
||||||
PlotVelocities = p.Results.PlotVelocities;
|
|
||||||
|
|
||||||
f_h = Helper.getFigureByTag('Trajectories Plot');
|
|
||||||
set(groot,'CurrentFigure',f_h);
|
|
||||||
a_h = get(f_h, 'CurrentAxes');
|
|
||||||
if ~isempty(get(a_h, 'Children'))
|
|
||||||
clf(f_h);
|
|
||||||
end
|
|
||||||
f_h.Name = 'Trajectories Plot';
|
|
||||||
f_h.Units = 'pixels';
|
|
||||||
|
|
||||||
set(0,'units','pixels');
|
|
||||||
screensize = get(0,'ScreenSize');
|
|
||||||
f_h.Position = [[screensize(3)/50 screensize(4)/3.5] 1870 600];
|
|
||||||
|
|
||||||
N = MOTObj.NumberOfAtoms;
|
|
||||||
Theta = IncidentAtomDirection;
|
|
||||||
z = IncidentAtomPosition;
|
|
||||||
|
|
||||||
L = OvenObj.OvenDistance * 2;
|
|
||||||
T = MOTObj.SimulationTime;
|
|
||||||
tau = MOTObj.TimeStep;
|
|
||||||
|
|
||||||
Y = linspace(0,MaximumVelocity,N);
|
|
||||||
DynamicalQuantities = zeros(length(Y),int64(T/tau),6);
|
|
||||||
for i=1:length(Y)
|
|
||||||
x =-L/2;
|
|
||||||
vx = Y(i)*cos(Theta);
|
|
||||||
vz = Y(i)*sin(Theta);
|
|
||||||
r = [x,0,z];
|
|
||||||
v = [vx,0,vz];
|
|
||||||
DynamicalQuantities(i,:,:) = MOTObj.solver(r, v);
|
|
||||||
end
|
|
||||||
|
|
||||||
LabelStringArrayForPositions = {'x (mm)', 'y (mm)', 'z (mm)'};
|
|
||||||
LabelStringArrayForVelocities = {'v_x (m/s)', 'v_y (m/s)', 'v_z (m/s)'};
|
|
||||||
colors = { [0, 0.4470, 0.7410], [0.8500, 0.3250, 0.0980], [0.4940, 0.1840, 0.5560]};
|
|
||||||
t = linspace(0, T, T/tau) * 1e+3;
|
|
||||||
for i=1:length(Y)
|
|
||||||
for j = 1:3
|
|
||||||
if PlotPositions
|
|
||||||
subplot(1, 3, j)
|
|
||||||
hold on
|
|
||||||
plot(t, DynamicalQuantities(i,:,j) * 1e+3,'Color', colors{j},'linewidth',1.3)
|
|
||||||
hXLabel = xlabel('Time (ms)');
|
|
||||||
hYLabel = ylabel(LabelStringArrayForPositions{j});
|
|
||||||
hold off
|
|
||||||
set([hXLabel, hYLabel], 'FontSize', 14);
|
|
||||||
elseif PlotVelocities
|
|
||||||
subplot(1, 3, j)
|
|
||||||
hold on
|
|
||||||
plot(t, DynamicalQuantities(i,:,j+3),'Color', colors{j},'linewidth',1.3)
|
|
||||||
hXLabel = xlabel('Time (ms)');
|
|
||||||
hYLabel = ylabel(LabelStringArrayForVelocities{j});
|
|
||||||
hold off
|
|
||||||
set([hXLabel, hYLabel], 'FontSize', 14);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
hold off
|
|
||||||
hTitle = sgtitle(sprintf("Magnetic gradient = %.2f T/m", MOTObj.MagneticGradient));
|
|
||||||
set(hTitle, 'FontSize', 18);
|
|
||||||
Helper.bringFiguresWithTagInForeground();
|
|
||||||
end
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
|||||||
function plotFreeMolecularFluxVsTemp(obj, Temperature)
|
|
||||||
|
|
||||||
f_h = Helper.getFigureByTag('Tube Flux');
|
|
||||||
set(groot,'CurrentFigure',f_h);
|
|
||||||
a_h = get(f_h, 'CurrentAxes');
|
|
||||||
if ~isempty(get(a_h, 'Children'))
|
|
||||||
clf(f_h);
|
|
||||||
end
|
|
||||||
f_h.Name = 'Tube Flux';
|
|
||||||
f_h.Units = 'pixels';
|
|
||||||
|
|
||||||
set(0,'units','pixels');
|
|
||||||
screensize = get(0,'ScreenSize');
|
|
||||||
f_h.Position = [[screensize(3)/4.5 screensize(4)/4.5] 920 750];
|
|
||||||
|
|
||||||
hold on
|
|
||||||
|
|
||||||
for i=1:length(Temperature)
|
|
||||||
beta = linspace(0.01,0.5,200);
|
|
||||||
obj.OvenTemperature = Temperature(i);
|
|
||||||
flux = zeros(1,length(beta));
|
|
||||||
for j=1:length(beta)
|
|
||||||
obj.NozzleLength = (2 * obj.NozzleRadius) / beta(j);
|
|
||||||
[ReducedClausingFactor, ~] = obj.calculateReducedClausingFactor();
|
|
||||||
flux(j) = ReducedClausingFactor * obj.calculateFreeMolecularRegimeFlux();
|
|
||||||
end
|
|
||||||
plot(beta, flux, 'DisplayName', sprintf('T = %.1f ℃', Temperature(i)), 'Linewidth', 1.5)
|
|
||||||
end
|
|
||||||
set(gca,'yscale','log')
|
|
||||||
|
|
||||||
obj.restoreDefaults();
|
|
||||||
|
|
||||||
xline(obj.Beta, 'k--','Linewidth', 0.5);
|
|
||||||
fmf = obj.ReducedClausingFactor * obj.calculateFreeMolecularRegimeFlux();
|
|
||||||
yline(fmf, 'k--', 'Linewidth', 1.5);
|
|
||||||
textstring = [sprintf('%1.e',fmf) ' atoms/s for ' '$$ \beta $$ = ' num2str(obj.Beta, '%.2f') sprintf(' @ %.2f K', obj.OvenTemperatureinKelvin)];
|
|
||||||
txt = text((obj.Beta + 0.05*obj.Beta), (max(fmf) + 0.2*fmf), textstring, 'Interpreter','latex');
|
|
||||||
|
|
||||||
hold off
|
|
||||||
|
|
||||||
leg = legend('Location', 'southeast');
|
|
||||||
leg.String = leg.String(1:end-2); % Remove xline and yline legend entries
|
|
||||||
hXLabel = xlabel('\beta');
|
|
||||||
hYLabel = ylabel('Flux (atoms/s)');
|
|
||||||
hTitle = sgtitle('Total Flux from a Tube (Free Molecular Flow)');
|
|
||||||
|
|
||||||
set([hXLabel, hYLabel, txt, leg] , ...
|
|
||||||
'FontSize' , 14 );
|
|
||||||
set( hTitle , ...
|
|
||||||
'FontSize' , 18 );
|
|
||||||
|
|
||||||
grid on
|
|
||||||
Helper.bringFiguresWithTagInForeground();
|
|
||||||
end
|
|
@ -1,72 +0,0 @@
|
|||||||
function plotInitialVeloctiySamplingVsAngle(obj, MOTObj, NumberOfBins)
|
|
||||||
n = obj.NumberOfAtoms;
|
|
||||||
VelocitySamples = obj.initialVelocitySampling(MOTObj);
|
|
||||||
|
|
||||||
Speeds = zeros(length(VelocitySamples),1);
|
|
||||||
Angles = zeros(length(VelocitySamples),1);
|
|
||||||
|
|
||||||
for i=1:length(VelocitySamples)
|
|
||||||
Speeds(i) = sqrt(VelocitySamples(i,1)^2+VelocitySamples(i,2)^2+VelocitySamples(i,3)^2);
|
|
||||||
Angles(i) = acos(VelocitySamples(i,1)/Speeds(i));
|
|
||||||
end
|
|
||||||
|
|
||||||
SpeedsArray = linspace(0,obj.VelocityCutoff,5000);
|
|
||||||
SpeedBinSize = obj.VelocityCutoff / NumberOfBins;
|
|
||||||
VelocityDistribution = @(velocity) sqrt(2 / pi) * sqrt(Helper.PhysicsConstants.Dy164Mass/(Helper.PhysicsConstants.BoltzmannConstant * obj.OvenTemperatureinKelvin))^3 ...
|
|
||||||
* velocity.^3 .* exp(-velocity.^2 .* (Helper.PhysicsConstants.Dy164Mass / (2 * Helper.PhysicsConstants.BoltzmannConstant ...
|
|
||||||
* obj.OvenTemperatureinKelvin)));
|
|
||||||
c = integral(VelocityDistribution, 0, obj.VelocityCutoff);
|
|
||||||
|
|
||||||
AnglesArray = linspace(0, obj.ExitDivergence,1000);
|
|
||||||
AngleBinSize = obj.ExitDivergence / NumberOfBins;
|
|
||||||
dtheta = AnglesArray(2)-AnglesArray(1);
|
|
||||||
AngularDistribution = zeros(1,length(AnglesArray));
|
|
||||||
d = 0;
|
|
||||||
for i = 1:length(AnglesArray)
|
|
||||||
AngularDistribution(i) = obj.angularDistributionFunction(AnglesArray(i));
|
|
||||||
d = d + (2 * pi * AngularDistribution(i) * sin(AnglesArray(i)) * dtheta);
|
|
||||||
end
|
|
||||||
AngularDistribution = AngularDistribution .* (2 * pi .* sin(AnglesArray));
|
|
||||||
|
|
||||||
f_h = Helper.getFigureByTag('Velocity Sampling');
|
|
||||||
set(groot,'CurrentFigure',f_h);
|
|
||||||
a_h = get(f_h, 'CurrentAxes');
|
|
||||||
if ~isempty(get(a_h, 'Children'))
|
|
||||||
clf(f_h);
|
|
||||||
end
|
|
||||||
f_h.Name = 'Velocity Sampling';
|
|
||||||
f_h.Units = 'pixels';
|
|
||||||
|
|
||||||
set(0,'units','pixels');
|
|
||||||
screensize = get(0,'ScreenSize');
|
|
||||||
f_h.Position = [[screensize(3)/10 screensize(4)/4] 1570,600];
|
|
||||||
|
|
||||||
subplot(1,2,1)
|
|
||||||
h_1 = histogram(Speeds, NumberOfBins,'FaceAlpha',0.4, 'EdgeAlpha',0.4);
|
|
||||||
hold on
|
|
||||||
plot(SpeedsArray, n/c * SpeedBinSize .* VelocityDistribution(SpeedsArray),'--', 'Linewidth',1.5)
|
|
||||||
xline(obj.VelocityCutoff, 'k--', 'Linewidth', 1.5);
|
|
||||||
text((obj.VelocityCutoff - 0.2 * obj.VelocityCutoff), max(h_1.Values) + 0.01 * max(h_1.Values), 'Cut-Off ---------->');
|
|
||||||
hXLabel_1 = xlabel('|v| (m/s)');
|
|
||||||
hYLabel_1 = ylabel('Counts');
|
|
||||||
hold off
|
|
||||||
|
|
||||||
subplot(1,2,2)
|
|
||||||
histogram(Angles .* 1e+03, NumberOfBins,'FaceAlpha',0.4, 'EdgeAlpha',0.4)
|
|
||||||
hold on
|
|
||||||
plot(AnglesArray .* 1e+03, (n/d * AngleBinSize .* AngularDistribution),'--', 'Linewidth',1.5)
|
|
||||||
xline(obj.ExitDivergence.* 1e+03, 'k--', 'Linewidth', 1.5);
|
|
||||||
text((obj.ExitDivergence - 0.5 * obj.ExitDivergence).* 1e+03, max(h_1.Values) - 0.45 * max(h_1.Values), 'Maximum Allowed Divergence ----------->');
|
|
||||||
hXLabel_2 = xlabel('\theta (mrad)');
|
|
||||||
hYLabel_2 = ylabel('Counts');
|
|
||||||
hold off
|
|
||||||
|
|
||||||
hTitle = sgtitle('Sampled Velocities');
|
|
||||||
|
|
||||||
set([hXLabel_1, hXLabel_2, hYLabel_1, hYLabel_2] , ...
|
|
||||||
'FontSize' , 14 );
|
|
||||||
set( hTitle , ...
|
|
||||||
'FontSize' , 18 );
|
|
||||||
|
|
||||||
Helper.bringFiguresWithTagInForeground();
|
|
||||||
end
|
|
@ -1,43 +0,0 @@
|
|||||||
function plotMeanFreePathAndVapourPressureVsTemp(TemperatureinCelsius)
|
|
||||||
|
|
||||||
TemperatureinKelvin = TemperatureinCelsius + 273.15;
|
|
||||||
|
|
||||||
Dy164VapourPressure = 133.322*exp(11.4103-2.3785e+04./(-219.4821+TemperatureinKelvin)); % Vapor Pressure Dysprosium for the given oven temperature
|
|
||||||
MeanFreepath = (Helper.PhysicsConstants.BoltzmannConstant*TemperatureinKelvin)./(sqrt(2) * ( pi * (2*281e-12)^2) * Dy164VapourPressure); %free path at above tempeture
|
|
||||||
|
|
||||||
f_h = Helper.getFigureByTag('Dysprosium Gas Properties');
|
|
||||||
set(groot,'CurrentFigure',f_h);
|
|
||||||
a_h = get(f_h, 'CurrentAxes');
|
|
||||||
if ~isempty(get(a_h, 'Children'))
|
|
||||||
clf(f_h);
|
|
||||||
end
|
|
||||||
f_h.Name = 'Dysprosium Gas Properties';
|
|
||||||
f_h.Units = 'pixels';
|
|
||||||
|
|
||||||
set(0,'units','pixels');
|
|
||||||
screensize = get(0,'ScreenSize');
|
|
||||||
f_h.Position = [[screensize(3)/3.5 screensize(4)/3.5] 750 600];
|
|
||||||
|
|
||||||
yyaxis left
|
|
||||||
semilogy(TemperatureinCelsius, Dy164VapourPressure, 'Color', '#0071BB', 'Linewidth',1.5);
|
|
||||||
hYLabel_1 = ylabel('Vapor Pressure (mbar)');
|
|
||||||
yyaxis right
|
|
||||||
semilogy(TemperatureinCelsius, MeanFreepath.*1000, 'Color', '#36B449', 'Linewidth',1.5)
|
|
||||||
hYLabel_2 = ylabel('Mean Free Path (mm)');
|
|
||||||
|
|
||||||
hXLabel = xlabel('Temperature (℃)');
|
|
||||||
|
|
||||||
ax = gca;
|
|
||||||
ax.YAxis(1).Color = '#0071BB';
|
|
||||||
ax.YAxis(2).Color = '#36B449';
|
|
||||||
|
|
||||||
hTitle = sgtitle('^{164}Dy Gas');
|
|
||||||
|
|
||||||
set([hXLabel, hYLabel_1, hYLabel_2] , ...
|
|
||||||
'FontSize' , 14 );
|
|
||||||
set( hTitle , ...
|
|
||||||
'FontSize' , 18 );
|
|
||||||
|
|
||||||
grid on
|
|
||||||
Helper.bringFiguresWithTagInForeground();
|
|
||||||
end
|
|
@ -1,84 +0,0 @@
|
|||||||
function plotPhaseSpaceWithAccelerationField(OvenObj, MOTObj, MinimumVelocity, MaximumVelocity, NumberOfBins, IncidentAtomDirection, IncidentAtomPosition)
|
|
||||||
f_h = Helper.getFigureByTag('Phase Space Plot');
|
|
||||||
set(groot,'CurrentFigure',f_h);
|
|
||||||
a_h = get(f_h, 'CurrentAxes');
|
|
||||||
if ~isempty(get(a_h, 'Children'))
|
|
||||||
clf(f_h);
|
|
||||||
end
|
|
||||||
f_h.Name = 'Phase Space Plot';
|
|
||||||
f_h.Units = 'pixels';
|
|
||||||
|
|
||||||
set(0,'units','pixels');
|
|
||||||
screensize = get(0,'ScreenSize');
|
|
||||||
f_h.Position = [[screensize(3)/3.5 screensize(4)/3.5] 750 600];
|
|
||||||
|
|
||||||
N = MOTObj.NumberOfAtoms;
|
|
||||||
L = OvenObj.OvenDistance * 2;
|
|
||||||
Theta = IncidentAtomDirection;
|
|
||||||
z = IncidentAtomPosition;
|
|
||||||
T = MOTObj.SimulationTime;
|
|
||||||
tau = MOTObj.TimeStep;
|
|
||||||
|
|
||||||
[X,Y] = meshgrid(-L/2:L/NumberOfBins:L/2,-MaximumVelocity:2*MaximumVelocity/NumberOfBins:MaximumVelocity);
|
|
||||||
|
|
||||||
a=zeros(NumberOfBins+1,NumberOfBins+1,3);
|
|
||||||
|
|
||||||
% MOTObj.restoreDefaults();
|
|
||||||
|
|
||||||
for i=1:length(X)
|
|
||||||
for j=1:length(Y)
|
|
||||||
a(i,j,:) = MOTObj.calculateTotalAcceleration([X(1,i), 0, z], [Y(j,1)*cos(Theta),0,Y(j,1)*sin(Theta)]);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for i=1:length(X)
|
|
||||||
for j=1:length(Y)
|
|
||||||
if isnan(a(i,j,1)) || isnan(a(i,j,2)) || isnan(a(i,j,3))
|
|
||||||
a(i,j,1)=0;
|
|
||||||
a(i,j,2)=0;
|
|
||||||
a(i,j,3)=0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
pcolor(X',Y',a(:,:,1))
|
|
||||||
hold on
|
|
||||||
col=colorbar;
|
|
||||||
col.Label.String='Aceleration (m/s^2)';
|
|
||||||
shading flat
|
|
||||||
|
|
||||||
%-------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Y = linspace(MinimumVelocity, MaximumVelocity,N);
|
|
||||||
DynamicalQuantities = zeros(length(Y),int64(T/tau),6);
|
|
||||||
for i=1:length(Y)
|
|
||||||
x =-L/2;
|
|
||||||
vx = Y(i)*cos(Theta);
|
|
||||||
vz = Y(i)*sin(Theta);
|
|
||||||
r = [x,0,z];
|
|
||||||
v = [vx,0,vz];
|
|
||||||
DynamicalQuantities(i,:,:) = MOTObj.solver(r, v);
|
|
||||||
end
|
|
||||||
|
|
||||||
hold on
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
for i=1:length(Y)
|
|
||||||
if DynamicalQuantities(i,end,2) > 0
|
|
||||||
plot(DynamicalQuantities(i,:,1),DynamicalQuantities(i,:,4),'w','linewidth',1.3)
|
|
||||||
count = count + 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
hold off
|
|
||||||
|
|
||||||
hXLabel = xlabel('Position: Along the x-axis (m)');
|
|
||||||
hYLabel = ylabel('Velocity (m/s)');
|
|
||||||
hTitle = sgtitle(sprintf("Magnetic gradient = %.3f T/m", MOTObj.MagneticGradient));
|
|
||||||
set([hXLabel, hYLabel] , ...
|
|
||||||
'FontSize' , 14 );
|
|
||||||
set( hTitle , ...
|
|
||||||
'FontSize' , 18 );
|
|
||||||
|
|
||||||
Helper.bringFiguresWithTagInForeground();
|
|
||||||
end
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
|||||||
function plotPositionAndVelocitySampling(NumberOfBins, initialPositions, initialVelocities)
|
|
||||||
|
|
||||||
f_h = Helper.getFigureByTag('RejectionSampling');
|
|
||||||
set(groot,'CurrentFigure',f_h);
|
|
||||||
a_h = get(f_h, 'CurrentAxes');
|
|
||||||
if ~isempty(get(a_h, 'Children'))
|
|
||||||
clf(f_h);
|
|
||||||
end
|
|
||||||
f_h.Name = 'Sampling';
|
|
||||||
f_h.Units = 'pixels';
|
|
||||||
|
|
||||||
set(0,'units','pixels');
|
|
||||||
screensize = get(0,'ScreenSize');
|
|
||||||
f_h.Position = [[screensize(3)/7 screensize(4)/7] 1.357e+03 770];
|
|
||||||
|
|
||||||
subplot(3,2,1)
|
|
||||||
histogram(initialPositions(:, 1)*1e3,NumberOfBins, 'LineStyle', 'none', 'DisplayName','x-Component')
|
|
||||||
xlabel('Positions (mm)','FontSize', 14)
|
|
||||||
ylabel('Counts','FontSize', 14)
|
|
||||||
legend('FontSize', 14)
|
|
||||||
|
|
||||||
subplot(3,2,3)
|
|
||||||
histogram(initialPositions(:, 2)*1e3,NumberOfBins, 'LineStyle', 'none', 'DisplayName','y-Component')
|
|
||||||
xlabel('Positions (mm)','FontSize', 14)
|
|
||||||
ylabel('Counts','FontSize', 14)
|
|
||||||
legend('FontSize', 14)
|
|
||||||
|
|
||||||
subplot(3,2,5)
|
|
||||||
histogram(initialPositions(:, 3)*1e3,NumberOfBins, 'LineStyle', 'none', 'DisplayName','z-Component')
|
|
||||||
xlabel('Positions (mm)','FontSize', 14)
|
|
||||||
ylabel('Counts','FontSize', 14)
|
|
||||||
legend('FontSize', 14)
|
|
||||||
|
|
||||||
subplot(3,2,2)
|
|
||||||
histogram(initialVelocities(:, 1),NumberOfBins, 'LineStyle', 'none', 'DisplayName','x-Component')
|
|
||||||
xlabel('Velocities (m/s)','FontSize', 14)
|
|
||||||
ylabel('Counts','FontSize', 14)
|
|
||||||
legend('FontSize', 14)
|
|
||||||
|
|
||||||
subplot(3,2,4)
|
|
||||||
histogram(initialVelocities(:, 2),NumberOfBins, 'LineStyle', 'none', 'DisplayName','y-Component')
|
|
||||||
xlabel('Velocities (m/s)','FontSize', 14)
|
|
||||||
ylabel('Counts','FontSize', 14)
|
|
||||||
legend('FontSize', 14)
|
|
||||||
|
|
||||||
subplot(3,2,6)
|
|
||||||
histogram(initialVelocities(:, 3),NumberOfBins, 'LineStyle', 'none', 'DisplayName','z-Component')
|
|
||||||
xlabel('Velocities (m/s)','FontSize', 14)
|
|
||||||
ylabel('Counts','FontSize', 14)
|
|
||||||
legend('FontSize', 14)
|
|
||||||
|
|
||||||
sgtitle('Rejection sampling for initial distributions','FontSize', 18)
|
|
||||||
|
|
||||||
Helper.bringFiguresWithTagInForeground();
|
|
||||||
end
|
|
@ -1,90 +0,0 @@
|
|||||||
function plotResultForOneParameterScan(XParameter, YQuantity, varargin)
|
|
||||||
|
|
||||||
p = inputParser;
|
|
||||||
p.KeepUnmatched = true;
|
|
||||||
|
|
||||||
addRequired(p, 'ParameterArray', @isvector)
|
|
||||||
addRequired(p, 'QuantityOfInterestArray', @ismatrix)
|
|
||||||
|
|
||||||
addParameter(p, 'RescalingFactorForParameter', 1, @isscalar)
|
|
||||||
addParameter(p, 'XLabelString', 'X parameter', @ischar)
|
|
||||||
addParameter(p, 'ErrorsForYQuantity', false, @islogical)
|
|
||||||
addParameter(p, 'ErrorsArray', [], @isvector)
|
|
||||||
addParameter(p, 'CIForYQuantity', false, @islogical)
|
|
||||||
addParameter(p, 'CIArray', [], @ismatrix)
|
|
||||||
addParameter(p, 'RescalingFactorForYQuantity', 1, @isscalar)
|
|
||||||
addParameter(p, 'RemoveOutliers', false, @islogical)
|
|
||||||
addParameter(p, 'YLabelString', 'Y parameter', @ischar)
|
|
||||||
addParameter(p, 'TitleString', 'One-Parameter Scan', @ischar)
|
|
||||||
|
|
||||||
p.parse(XParameter, YQuantity, varargin{:})
|
|
||||||
|
|
||||||
XParameter = p.Results.ParameterArray;
|
|
||||||
RescalingFactorForXParameter = p.Results.RescalingFactorForParameter;
|
|
||||||
XLabelString = p.Results.XLabelString;
|
|
||||||
YQuantity = p.Results.QuantityOfInterestArray;
|
|
||||||
ErrorsForYQuantity = p.Results.ErrorsForYQuantity;
|
|
||||||
ErrorsArray = p.Results.ErrorsArray;
|
|
||||||
CIForYQuantity = p.Results.CIForYQuantity;
|
|
||||||
CIArray = p.Results.CIArray;
|
|
||||||
RescalingFactorForYQuantity = p.Results.RescalingFactorForYQuantity;
|
|
||||||
RemoveOutliers = p.Results.RemoveOutliers;
|
|
||||||
YLabelString = p.Results.YLabelString;
|
|
||||||
TitleString = p.Results.TitleString;
|
|
||||||
|
|
||||||
f_h = Helper.getFigureByTag('One-Parameter Scan');
|
|
||||||
set(groot,'CurrentFigure',f_h);
|
|
||||||
a_h = get(f_h, 'CurrentAxes');
|
|
||||||
if ~isempty(get(a_h, 'Children'))
|
|
||||||
clf(f_h);
|
|
||||||
end
|
|
||||||
f_h.Name = 'One-Parameter Scan';
|
|
||||||
f_h.Units = 'pixels';
|
|
||||||
|
|
||||||
set(0,'units','pixels');
|
|
||||||
screensize = get(0,'ScreenSize');
|
|
||||||
f_h.Position = [[screensize(3)/3.5 screensize(4)/3.5] 750 600];
|
|
||||||
|
|
||||||
if RemoveOutliers
|
|
||||||
[YQuantity,TF] = rmoutliers(YQuantity);
|
|
||||||
XParameter = XParameter(~TF);
|
|
||||||
ErrorsArray = ErrorsArray(~TF);
|
|
||||||
ClippedCIArray(:,1) = CIArray(~TF,1);
|
|
||||||
ClippedCIArray(:,2) = CIArray(~TF,2);
|
|
||||||
CIArray = ClippedCIArray;
|
|
||||||
end
|
|
||||||
|
|
||||||
RescaledXParameter = XParameter .* RescalingFactorForXParameter;
|
|
||||||
RescaledYQuantity = YQuantity .* RescalingFactorForYQuantity;
|
|
||||||
|
|
||||||
hold on
|
|
||||||
|
|
||||||
if ErrorsForYQuantity
|
|
||||||
RescaledErrorsArray = ErrorsArray .* RescalingFactorForYQuantity;
|
|
||||||
errorbar(RescaledXParameter, RescaledYQuantity, RescaledErrorsArray, 'o', 'Linewidth', 1.5, 'MarkerFaceColor', '#0071BB')
|
|
||||||
else
|
|
||||||
plot(RescaledXParameter, RescaledYQuantity, '--o', 'Linewidth', 1.5);
|
|
||||||
end
|
|
||||||
|
|
||||||
if CIForYQuantity
|
|
||||||
RescaledCIArray = CIArray .* RescalingFactorForYQuantity;
|
|
||||||
Plotter.plotConfidenceIntervalRegion(RescaledXParameter, RescaledCIArray(:,1), RescaledCIArray(:,2));
|
|
||||||
end
|
|
||||||
|
|
||||||
hold off
|
|
||||||
|
|
||||||
xlim([0 inf])
|
|
||||||
ylim([0 inf])
|
|
||||||
|
|
||||||
hXLabel = xlabel(XLabelString);
|
|
||||||
hYLabel = ylabel(YLabelString);
|
|
||||||
hTitle = sgtitle(TitleString);
|
|
||||||
|
|
||||||
set([hXLabel, hYLabel] , ...
|
|
||||||
'FontSize' , 14 );
|
|
||||||
set( hTitle , ...
|
|
||||||
'FontSize' , 18 );
|
|
||||||
|
|
||||||
grid on
|
|
||||||
Helper.bringFiguresWithTagInForeground();
|
|
||||||
end
|
|
@ -1,82 +0,0 @@
|
|||||||
function plotResultForThreeParameterScan(XParameter, YParameter, DeltaParameter, ZQuantity, varargin)
|
|
||||||
|
|
||||||
p = inputParser;
|
|
||||||
p.KeepUnmatched = true;
|
|
||||||
|
|
||||||
addRequired(p, 'FirstParameterArray', @isvector)
|
|
||||||
addRequired(p, 'SecondParameterArray', @isvector)
|
|
||||||
addRequired(p, 'ThirdParameterArray', @isvector)
|
|
||||||
addRequired(p, 'QuantityOfInterestArray', @ismatrix)
|
|
||||||
|
|
||||||
addParameter(p, 'RescalingFactorForFirstParameter', 1, @isscalar)
|
|
||||||
addParameter(p, 'XLabelString', 'X parameter', @ischar)
|
|
||||||
addParameter(p, 'RescalingFactorForSecondParameter', 1, @isscalar)
|
|
||||||
addParameter(p, 'YLabelString', 'Y parameter', @ischar)
|
|
||||||
addParameter(p, 'RescalingFactorForThirdParameter', 1, @isscalar)
|
|
||||||
addParameter(p, 'RescalingFactorForQuantityOfInterest', 1, @isscalar)
|
|
||||||
addParameter(p, 'ZLabelString', 'Z parameter', @ischar)
|
|
||||||
addParameter(p, 'PlotTitleString', '<third parameter value>', @ischar)
|
|
||||||
addParameter(p, 'FigureTitleString', 'Third-Parameter Scan', @ischar)
|
|
||||||
|
|
||||||
p.parse(XParameter, YParameter, DeltaParameter, ZQuantity, varargin{:})
|
|
||||||
|
|
||||||
XParameter = p.Results.FirstParameterArray;
|
|
||||||
RescalingFactorForXParameter = p.Results.RescalingFactorForFirstParameter;
|
|
||||||
XLabelString = p.Results.XLabelString;
|
|
||||||
YParameter = p.Results.SecondParameterArray;
|
|
||||||
RescalingFactorForYParameter = p.Results.RescalingFactorForSecondParameter;
|
|
||||||
YLabelString = p.Results.YLabelString;
|
|
||||||
DeltaParameter = p.Results.ThirdParameterArray;
|
|
||||||
RescalingFactorForDeltaParameter = p.Results.RescalingFactorForThirdParameter;
|
|
||||||
ZQuantity = p.Results.QuantityOfInterestArray;
|
|
||||||
RescalingFactorForZQuantity = p.Results.RescalingFactorForQuantityOfInterest;
|
|
||||||
ZLabelString = p.Results.ZLabelString;
|
|
||||||
PlotTitleString = p.Results.PlotTitleString;
|
|
||||||
FigureTitleString = p.Results.FigureTitleString;
|
|
||||||
|
|
||||||
f_h = Helper.getFigureByTag('Three-Parameter Scan');
|
|
||||||
set(groot,'CurrentFigure',f_h);
|
|
||||||
a_h = get(f_h, 'CurrentAxes');
|
|
||||||
if ~isempty(get(a_h, 'Children'))
|
|
||||||
clf(f_h);
|
|
||||||
end
|
|
||||||
f_h.Name = 'Three-Parameter Scan';
|
|
||||||
f_h.Units = 'pixels';
|
|
||||||
|
|
||||||
set(0,'units','pixels');
|
|
||||||
screensize = get(0,'ScreenSize');
|
|
||||||
f_h.Position = [[screensize(3)/60 screensize(4)/10] 1530 870];
|
|
||||||
|
|
||||||
RescaledXParameter = XParameter .* RescalingFactorForXParameter;
|
|
||||||
RescaledYParameter = YParameter .* RescalingFactorForYParameter;
|
|
||||||
RescaledDeltaParameter = DeltaParameter .* RescalingFactorForDeltaParameter;
|
|
||||||
|
|
||||||
tiledlayout(ceil(length(DeltaParameter)/3), 3)
|
|
||||||
|
|
||||||
for i = 1:length(DeltaParameter)
|
|
||||||
nexttile
|
|
||||||
RescaledZQuantity = ZQuantity{i} .* RescalingFactorForZQuantity;
|
|
||||||
imagesc(RescaledXParameter, RescaledYParameter, RescaledZQuantity(:,:)');
|
|
||||||
set(gca,'YDir','normal');
|
|
||||||
hXLabel = xlabel(XLabelString);
|
|
||||||
hYLabel = ylabel(YLabelString);
|
|
||||||
hPlotLabel = title(sprintf(PlotTitleString, RescaledDeltaParameter(i)));
|
|
||||||
set([hXLabel, hYLabel, hPlotLabel] , ...
|
|
||||||
'FontSize' , 14);
|
|
||||||
end
|
|
||||||
|
|
||||||
caxis([min(min(min(RescaledZQuantity))) max(max(max(RescaledZQuantity)))]);
|
|
||||||
|
|
||||||
shading flat;
|
|
||||||
c = colorbar;
|
|
||||||
c.Label.String= ZLabelString;
|
|
||||||
c.Label.FontSize = 14;
|
|
||||||
c.Layout.Tile = 'east';
|
|
||||||
|
|
||||||
hTitle = sgtitle(FigureTitleString);
|
|
||||||
|
|
||||||
set( hTitle , ...
|
|
||||||
'FontSize' , 18 );
|
|
||||||
|
|
||||||
Helper.bringFiguresWithTagInForeground();
|
|
||||||
end
|
|
@ -1,74 +0,0 @@
|
|||||||
function plotResultForTwoParameterScan(XParameter, YParameter, ZQuantity, varargin)
|
|
||||||
|
|
||||||
p = inputParser;
|
|
||||||
p.KeepUnmatched = true;
|
|
||||||
|
|
||||||
addRequired(p, 'FirstParameterArray', @isvector)
|
|
||||||
addRequired(p, 'SecondParameterArray', @isvector)
|
|
||||||
addRequired(p, 'QuantityOfInterestArray', @ismatrix)
|
|
||||||
|
|
||||||
addParameter(p, 'RescalingFactorForFirstParameter', 1, @isscalar)
|
|
||||||
addParameter(p, 'XLabelString', 'X parameter', @ischar)
|
|
||||||
addParameter(p, 'RescalingFactorForSecondParameter', 1, @isscalar)
|
|
||||||
addParameter(p, 'YLabelString', 'Y parameter', @ischar)
|
|
||||||
addParameter(p, 'RescalingFactorForQuantityOfInterest', 1, @isscalar)
|
|
||||||
addParameter(p, 'ZLabelString', 'Z parameter', @ischar)
|
|
||||||
addParameter(p, 'TitleString', 'Two-Parameter Scan', @ischar)
|
|
||||||
|
|
||||||
p.parse(XParameter, YParameter, ZQuantity, varargin{:})
|
|
||||||
|
|
||||||
XParameter = p.Results.FirstParameterArray;
|
|
||||||
RescalingFactorForXParameter = p.Results.RescalingFactorForFirstParameter;
|
|
||||||
XLabelString = p.Results.XLabelString;
|
|
||||||
YParameter = p.Results.SecondParameterArray;
|
|
||||||
RescalingFactorForYParameter = p.Results.RescalingFactorForSecondParameter;
|
|
||||||
YLabelString = p.Results.YLabelString;
|
|
||||||
ZQuantity = p.Results.QuantityOfInterestArray;
|
|
||||||
RescalingFactorForZQuantity = p.Results.RescalingFactorForQuantityOfInterest;
|
|
||||||
ZLabelString = p.Results.ZLabelString;
|
|
||||||
TitleString = p.Results.TitleString;
|
|
||||||
|
|
||||||
f_h = Helper.getFigureByTag('Two-Parameter Scan');
|
|
||||||
set(groot,'CurrentFigure',f_h);
|
|
||||||
a_h = get(f_h, 'CurrentAxes');
|
|
||||||
if ~isempty(get(a_h, 'Children'))
|
|
||||||
clf(f_h);
|
|
||||||
end
|
|
||||||
f_h.Name = 'Two-Parameter Scan';
|
|
||||||
f_h.Units = 'pixels';
|
|
||||||
|
|
||||||
set(0,'units','pixels');
|
|
||||||
screensize = get(0,'ScreenSize');
|
|
||||||
f_h.Position = [[screensize(3)/3.5 screensize(4)/3.5] 750 600];
|
|
||||||
|
|
||||||
RescaledXParameter = XParameter .* RescalingFactorForXParameter;
|
|
||||||
RescaledYParameter = YParameter .* RescalingFactorForYParameter;
|
|
||||||
RescaledZQuantity = ZQuantity .* RescalingFactorForZQuantity;
|
|
||||||
|
|
||||||
imagesc(RescaledXParameter, RescaledYParameter, RescaledZQuantity(:,:)');
|
|
||||||
|
|
||||||
% hold on
|
|
||||||
%
|
|
||||||
% contour(RescaledXParameter, RescaledYParameter, RescaledZQuantity(:,:)', 'Color', 'r', 'Linewidth', 4, 'ShowText','on')
|
|
||||||
|
|
||||||
set(gca,'YDir','normal');
|
|
||||||
|
|
||||||
caxis([min(min(min(RescaledZQuantity))) max(max(max(RescaledZQuantity)))]);
|
|
||||||
|
|
||||||
hXLabel = xlabel(XLabelString);
|
|
||||||
hYLabel = ylabel(YLabelString);
|
|
||||||
|
|
||||||
shading flat;
|
|
||||||
c = colorbar;
|
|
||||||
c.Label.String= ZLabelString;
|
|
||||||
c.Label.FontSize = 14;
|
|
||||||
|
|
||||||
hTitle = sgtitle(TitleString);
|
|
||||||
|
|
||||||
set([hXLabel, hYLabel] , ...
|
|
||||||
'FontSize' , 14 );
|
|
||||||
set( hTitle , ...
|
|
||||||
'FontSize' , 18 );
|
|
||||||
|
|
||||||
Helper.bringFiguresWithTagInForeground();
|
|
||||||
end
|
|
@ -1,72 +0,0 @@
|
|||||||
function visualizeMagneticField(obj, x_range, y_range, z_range)
|
|
||||||
|
|
||||||
f_h = Helper.getFigureByTag('VisualizeMagneticFieldFor2DMOT');
|
|
||||||
set(groot,'CurrentFigure',f_h);
|
|
||||||
a_h = get(f_h, 'CurrentAxes');
|
|
||||||
if ~isempty(get(a_h, 'Children'))
|
|
||||||
clf(f_h);
|
|
||||||
end
|
|
||||||
f_h.Name = 'Visualization';
|
|
||||||
f_h.Units = 'pixels';
|
|
||||||
|
|
||||||
set(0,'units','pixels');
|
|
||||||
screensize = get(0,'ScreenSize');
|
|
||||||
f_h.Position = [[screensize(3)/3.5 screensize(4)/3.5] 820 645];
|
|
||||||
|
|
||||||
xmin = x_range(1);
|
|
||||||
xmax = x_range(2);
|
|
||||||
ymin = y_range(1);
|
|
||||||
ymax = y_range(2);
|
|
||||||
zmin = z_range(1);
|
|
||||||
zmax = z_range(2);
|
|
||||||
dx = (xmax-xmin)/8;
|
|
||||||
dy = (ymax-ymin)/8;
|
|
||||||
dz = (zmax-zmin)/8;
|
|
||||||
if dx ~= 0
|
|
||||||
xm = xmin:dx:xmax;
|
|
||||||
else
|
|
||||||
xm = zeros(1,5);
|
|
||||||
end
|
|
||||||
|
|
||||||
if dy ~= 0
|
|
||||||
ym = ymin:dy:ymax;
|
|
||||||
else
|
|
||||||
ym = zeros(1,5);
|
|
||||||
end
|
|
||||||
|
|
||||||
if dz ~= 0
|
|
||||||
zm = zmin:dz:zmax;
|
|
||||||
else
|
|
||||||
zm = zeros(1,5);
|
|
||||||
end
|
|
||||||
[meshx,meshy,meshz] = meshgrid(xm,ym,zm); % construct data points
|
|
||||||
|
|
||||||
switch obj.SimulationMode
|
|
||||||
case '2D'
|
|
||||||
alpha = obj.MagneticGradient;
|
|
||||||
Bx = @(x,y,z) alpha .* z;
|
|
||||||
By = @(x,y,z) 0 .* y;
|
|
||||||
Bz = @(x,y,z) alpha .* x;
|
|
||||||
Bx_val = Bx(meshx, meshy, meshz);
|
|
||||||
By_val = By(meshx, meshy, meshz);
|
|
||||||
Bz_val = Bz(meshx, meshy, meshz);
|
|
||||||
case '3D'
|
|
||||||
% Development in progress
|
|
||||||
end
|
|
||||||
|
|
||||||
quiver3(meshx, meshy, meshz, Bx_val, By_val, Bz_val, 'Color', ' #6600ff');
|
|
||||||
axis equal
|
|
||||||
|
|
||||||
hXLabel = xlabel('x');
|
|
||||||
hYLabel = ylabel('y');
|
|
||||||
hZLabel = zlabel('z');
|
|
||||||
|
|
||||||
hTitle = sgtitle('Magnetic Field for 2-D MOT');
|
|
||||||
|
|
||||||
set([hXLabel, hYLabel, hZLabel] , ...
|
|
||||||
'FontSize' , 14 );
|
|
||||||
set( hTitle , ...
|
|
||||||
'FontSize' , 18 );
|
|
||||||
|
|
||||||
Helper.bringFiguresWithTagInForeground();
|
|
||||||
end
|
|
@ -1,236 +0,0 @@
|
|||||||
OptionsStruct = struct;
|
|
||||||
OptionsStruct.ErrorEstimationMethod = 'bootstrap'; % 'jackknife' | 'bootstrap'
|
|
||||||
OptionsStruct.NumberOfAtoms = 5000;
|
|
||||||
OptionsStruct.TimeStep = 50e-06; % in s
|
|
||||||
OptionsStruct.SimulationTime = 5e-03; % in s
|
|
||||||
OptionsStruct.SpontaneousEmission = true;
|
|
||||||
OptionsStruct.SidebandBeam = true;
|
|
||||||
OptionsStruct.PushBeam = true;
|
|
||||||
OptionsStruct.Gravity = true;
|
|
||||||
OptionsStruct.BackgroundCollision = true;
|
|
||||||
OptionsStruct.SaveData = true;
|
|
||||||
% OptionsStruct.SaveDirectory = '';
|
|
||||||
options = Helper.convertstruct2cell(OptionsStruct);
|
|
||||||
clear OptionsStruct
|
|
||||||
|
|
||||||
Oven = Simulator.Oven(options{:});
|
|
||||||
MOT2D = Simulator.TwoDimensionalMOT(options{:});
|
|
||||||
Beams = MOT2D.Beams;
|
|
||||||
|
|
||||||
%%
|
|
||||||
MOT2D.NumberOfAtoms = 10000;
|
|
||||||
MOT2D.TotalPower = 0.8;
|
|
||||||
MOT2D.MagneticGradient = 0.4; 0;
|
|
||||||
CoolingBeam = Beams{cellfun(@(x) strcmpi(x.Alias, 'Blue'), Beams)};
|
|
||||||
CoolingBeam.Waist = 15e-03;
|
|
||||||
CoolingBeam.Detuning = -1.67*Helper.PhysicsConstants.BlueLinewidth;
|
|
||||||
SidebandBeam = Beams{cellfun(@(x) strcmpi(x.Alias, 'BlueSideband'), Beams)};
|
|
||||||
SidebandBeam.Waist = 15e-03;
|
|
||||||
|
|
||||||
NumberOfPointsForFirstParam = 20; %iterations of the simulation
|
|
||||||
NumberOfPointsForSecondParam = 20;
|
|
||||||
DetuningArray = linspace(-1.0, -6.0, NumberOfPointsForFirstParam) * Helper.PhysicsConstants.BlueLinewidth;
|
|
||||||
PowerArray = linspace(0, 0.8, NumberOfPointsForSecondParam) * MOT2D.TotalPower;
|
|
||||||
|
|
||||||
tStart = tic;
|
|
||||||
[LoadingRateArray, ~, ~] = Scripts.scanForSidebandEnhancement(Oven, MOT2D, 'Blue', 'BlueSideband', DetuningArray, PowerArray);
|
|
||||||
tEnd = toc(tStart);
|
|
||||||
fprintf('Total Computational Time: %0.1f seconds. \n', tEnd);
|
|
||||||
|
|
||||||
if MOT2D.DoSave
|
|
||||||
LoadingRate = struct;
|
|
||||||
LoadingRate.Values = LoadingRateArray;
|
|
||||||
MOT2D.Results = LoadingRate;
|
|
||||||
SaveFolder = [MOT2D.SaveDirectory filesep 'Results'];
|
|
||||||
Filename = ['TwoParameterScan_' datestr(now,'yyyymmdd_HHMM')];
|
|
||||||
eval([sprintf('%s_Object', Filename) ' = MOT2D;']);
|
|
||||||
mkdir(SaveFolder);
|
|
||||||
save([SaveFolder filesep Filename], sprintf('%s_Object', Filename));
|
|
||||||
end
|
|
||||||
|
|
||||||
MOT2D.SidebandBeam = false;
|
|
||||||
MOT2D.PushBeam = false;
|
|
||||||
CoolingBeam.Power = MOT2D.TotalPower;
|
|
||||||
[LoadingRate, ~] = MOT2D.runSimulation(Oven);
|
|
||||||
|
|
||||||
EnhancementFactorArray = LoadingRateArray ./ LoadingRate;
|
|
||||||
|
|
||||||
% - Plot results
|
|
||||||
|
|
||||||
OptionsStruct = struct;
|
|
||||||
OptionsStruct.RescalingFactorForFirstParameter = (Helper.PhysicsConstants.BlueLinewidth)^-1;
|
|
||||||
OptionsStruct.XLabelString = 'Sideband Beam Detuning (\Delta/\Gamma)';
|
|
||||||
OptionsStruct.RescalingFactorForSecondParameter = 1000;
|
|
||||||
OptionsStruct.YLabelString = 'Sideband Beam Power (mW)';
|
|
||||||
OptionsStruct.RescalingFactorForQuantityOfInterest = 1;
|
|
||||||
OptionsStruct.ZLabelString = 'Enhancement Factor (\eta)';
|
|
||||||
% OptionsStruct.ZLabelString = 'Loading rate (x 10^{9} atoms/s)';
|
|
||||||
OptionsStruct.TitleString = sprintf('Magnetic Gradient = %.0f (G/cm)', MOT2D.MagneticGradient * 100);
|
|
||||||
|
|
||||||
options = Helper.convertstruct2cell(OptionsStruct);
|
|
||||||
Plotter.plotResultForTwoParameterScan(DetuningArray, PowerArray, EnhancementFactorArray, options{:})
|
|
||||||
|
|
||||||
%% Magnetic gradient scan
|
|
||||||
|
|
||||||
MOT2D.NumberOfAtoms = 10000;
|
|
||||||
MOT2D.TotalPower = 0.4;
|
|
||||||
MOT2D.SidebandBeam = true;
|
|
||||||
NumberOfPointsForFirstParam = 10; %iterations of the simulation
|
|
||||||
NumberOfPointsForSecondParam = 10;
|
|
||||||
NumberOfPointsForThirdParam = 6;
|
|
||||||
DetuningArray = linspace(-0.5, -5.0, NumberOfPointsForFirstParam) * Helper.PhysicsConstants.BlueLinewidth;
|
|
||||||
PowerArray = linspace(0.1, 1.0, NumberOfPointsForSecondParam) * MOT2D.TotalPower;
|
|
||||||
MagneticGradientArray = linspace(30, 50, NumberOfPointsForThirdParam) * 1e-02;
|
|
||||||
Beams = MOT2D.Beams;
|
|
||||||
CoolingBeam = Beams{cellfun(@(x) strcmpi(x.Alias, 'Blue'), Beams)};
|
|
||||||
SidebandBeam = Beams{cellfun(@(x) strcmpi(x.Alias, 'BlueSideband'), Beams)};
|
|
||||||
LoadingRateArray = {};
|
|
||||||
|
|
||||||
tStart = tic;
|
|
||||||
for k=1:NumberOfPointsForThirdParam
|
|
||||||
eval(sprintf('MOT2D.%s = %d;', 'MagneticGradient', MagneticGradientArray(k)));
|
|
||||||
lrmatrix = zeros(NumberOfPointsForFirstParam, NumberOfPointsForSecondParam);
|
|
||||||
for i=1:NumberOfPointsForFirstParam
|
|
||||||
eval(sprintf('SidebandBeam.%s = %d;', 'Detuning', DetuningArray(i)));
|
|
||||||
for j=1:NumberOfPointsForSecondParam
|
|
||||||
eval(sprintf('SidebandBeam.%s = %d;', 'Power', PowerArray(j)));
|
|
||||||
eval(sprintf('CoolingBeam.%s = %d;', 'Power', MOT2D.TotalPower - PowerArray(j)));
|
|
||||||
[lrmatrix(i,j), ~, ~] = MOT2D.runSimulation(Oven);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
LoadingRateArray{end+1} = lrmatrix;
|
|
||||||
end
|
|
||||||
|
|
||||||
tEnd = toc(tStart);
|
|
||||||
fprintf('Total Computational Time: %0.1f seconds. \n', tEnd);
|
|
||||||
|
|
||||||
% - Plot results
|
|
||||||
|
|
||||||
OptionsStruct = struct;
|
|
||||||
OptionsStruct.RescalingFactorForFirstParameter = (Helper.PhysicsConstants.BlueLinewidth)^-1;
|
|
||||||
OptionsStruct.XLabelString = 'Sideband Beam Detuning (\Delta/\Gamma)';
|
|
||||||
OptionsStruct.RescalingFactorForSecondParameter = 1000;
|
|
||||||
OptionsStruct.YLabelString = 'Sideband Beam Waist (mm)';
|
|
||||||
OptionsStruct.RescalingFactorForThirdParameter = 100;
|
|
||||||
OptionsStruct.RescalingFactorForQuantityOfInterest = 1e-9;
|
|
||||||
OptionsStruct.ZLabelString = 'Loading rate (x 10^{9} atoms/s)';
|
|
||||||
OptionsStruct.PlotTitleString = 'Magnetic Gradient = %.0f (G/cm)';
|
|
||||||
OptionsStruct.FigureTitleString = sprintf('Oven-2DMOT Distance = %.1f (mm); Total Beam Power = %d (mW)', Oven.OvenDistance * 1000, MOT2D.TotalPower*1000);
|
|
||||||
|
|
||||||
options = Helper.convertstruct2cell(OptionsStruct);
|
|
||||||
|
|
||||||
Plotter.plotResultForThreeParameterScan(DetuningArray, PowerArray, MagneticGradientArray, LoadingRateArray, options{:})
|
|
||||||
|
|
||||||
clear OptionsStruct
|
|
||||||
|
|
||||||
%%
|
|
||||||
MOT2D.NumberOfAtoms = 10000;
|
|
||||||
MOT2D.TotalPower = 0.4;
|
|
||||||
MOT2D.MagneticGradient = 0.4; 0;
|
|
||||||
CoolingBeam = Beams{cellfun(@(x) strcmpi(x.Alias, 'Blue'), Beams)};
|
|
||||||
CoolingBeam.Power = 0.2;
|
|
||||||
CoolingBeam.Detuning = -1.3*Helper.PhysicsConstants.BlueLinewidth;
|
|
||||||
SidebandBeam = Beams{cellfun(@(x) strcmpi(x.Alias, 'BlueSideband'), Beams)};
|
|
||||||
SidebandBeam.Power = 0.2;
|
|
||||||
NumberOfPointsForFirstParam = 20; %iterations of the simulation
|
|
||||||
NumberOfPointsForSecondParam = 20;
|
|
||||||
DetuningArray = linspace(-1.0, -6.0, NumberOfPointsForFirstParam) * Helper.PhysicsConstants.BlueLinewidth;
|
|
||||||
BeamWaistArray = linspace(10, 25, NumberOfPointsForSecondParam) * 1e-03;
|
|
||||||
|
|
||||||
tStart = tic;
|
|
||||||
LoadingRateArray = zeros(NumberOfPointsForFirstParam, NumberOfPointsForSecondParam);
|
|
||||||
StandardErrorArray = zeros(NumberOfPointsForFirstParam, NumberOfPointsForSecondParam);
|
|
||||||
ConfidenceIntervalArray = zeros(NumberOfPointsForFirstParam, NumberOfPointsForSecondParam, 2);
|
|
||||||
|
|
||||||
for i=1:NumberOfPointsForFirstParam
|
|
||||||
eval(sprintf('SidebandBeam.Detuning = %d;', DetuningArray(i)));
|
|
||||||
for j=1:NumberOfPointsForSecondParam
|
|
||||||
eval(sprintf('CoolingBeam.Waist = %d;', BeamWaistArray(j)));
|
|
||||||
eval(sprintf('SidebandBeam.Waist = %d;', BeamWaistArray(j)));
|
|
||||||
[LoadingRateArray(i,j), StandardErrorArray(i,j), ConfidenceIntervalArray(i,j,:)] = MOT2D.runSimulation(Oven);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
tEnd = toc(tStart);
|
|
||||||
fprintf('Total Computational Time: %0.1f seconds. \n', tEnd);
|
|
||||||
|
|
||||||
if MOT2D.DoSave
|
|
||||||
LoadingRate = struct;
|
|
||||||
LoadingRate.Values = LoadingRateArray;
|
|
||||||
MOT2D.Results = LoadingRate;
|
|
||||||
SaveFolder = [MOT2D.SaveDirectory filesep 'Results'];
|
|
||||||
Filename = ['TwoParameterScan_' datestr(now,'yyyymmdd_HHMM')];
|
|
||||||
eval([sprintf('%s_Object', Filename) ' = MOT2D;']);
|
|
||||||
mkdir(SaveFolder);
|
|
||||||
save([SaveFolder filesep Filename], sprintf('%s_Object', Filename));
|
|
||||||
end
|
|
||||||
|
|
||||||
% - Plot results
|
|
||||||
|
|
||||||
OptionsStruct = struct;
|
|
||||||
OptionsStruct.RescalingFactorForFirstParameter = (Helper.PhysicsConstants.BlueLinewidth)^-1;
|
|
||||||
OptionsStruct.XLabelString = 'Sideband Beam Detuning (\Delta/\Gamma)';
|
|
||||||
OptionsStruct.RescalingFactorForSecondParameter = 1000;
|
|
||||||
OptionsStruct.YLabelString = 'Beam Waist (mW)';
|
|
||||||
OptionsStruct.RescalingFactorForQuantityOfInterest = 1e-10;
|
|
||||||
% OptionsStruct.ZLabelString = 'Enhancement Factor (\eta)';
|
|
||||||
OptionsStruct.ZLabelString = 'Loading rate (x 10^{10} atoms/s)';
|
|
||||||
OptionsStruct.TitleString = sprintf('Magnetic Gradient = %.0f (G/cm)', MOT2D.MagneticGradient * 100);
|
|
||||||
|
|
||||||
options = Helper.convertstruct2cell(OptionsStruct);
|
|
||||||
Plotter.plotResultForTwoParameterScan(DetuningArray, BeamWaistArray, LoadingRateArray, options{:})
|
|
||||||
|
|
||||||
%%
|
|
||||||
MOT2D.NumberOfAtoms = 10000;
|
|
||||||
MOT2D.TotalPower = 0.4;
|
|
||||||
MOT2D.MagneticGradient = 0.4; 0;
|
|
||||||
CoolingBeam = Beams{cellfun(@(x) strcmpi(x.Alias, 'Blue'), Beams)};
|
|
||||||
CoolingBeam.Power = 0.2;
|
|
||||||
SidebandBeam = Beams{cellfun(@(x) strcmpi(x.Alias, 'BlueSideband'), Beams)};
|
|
||||||
SidebandBeam.Power = 0.2;
|
|
||||||
NumberOfPointsForFirstParam = 20; %iterations of the simulation
|
|
||||||
NumberOfPointsForSecondParam = 20;
|
|
||||||
DetuningArray = linspace(-0.5, -2.5, NumberOfPointsForFirstParam) * Helper.PhysicsConstants.BlueLinewidth;
|
|
||||||
BeamWaistArray = linspace(10, 25, NumberOfPointsForSecondParam) * 1e-03;
|
|
||||||
|
|
||||||
tStart = tic;
|
|
||||||
LoadingRateArray = zeros(NumberOfPointsForFirstParam, NumberOfPointsForSecondParam);
|
|
||||||
StandardErrorArray = zeros(NumberOfPointsForFirstParam, NumberOfPointsForSecondParam);
|
|
||||||
ConfidenceIntervalArray = zeros(NumberOfPointsForFirstParam, NumberOfPointsForSecondParam, 2);
|
|
||||||
|
|
||||||
for i=1:NumberOfPointsForFirstParam
|
|
||||||
eval(sprintf('CoolingBeam.Detuning = %d;', DetuningArray(i)));
|
|
||||||
eval(sprintf('SidebandBeam.Detuning = %d;', DetuningArray(i) - (1.0 * Helper.PhysicsConstants.BlueLinewidth)));
|
|
||||||
for j=1:NumberOfPointsForSecondParam
|
|
||||||
eval(sprintf('CoolingBeam.Waist = %d;', BeamWaistArray(j)));
|
|
||||||
eval(sprintf('SidebandBeam.Waist = %d;', BeamWaistArray(j)));
|
|
||||||
[LoadingRateArray(i,j), StandardErrorArray(i,j), ConfidenceIntervalArray(i,j,:)] = MOT2D.runSimulation(Oven);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
tEnd = toc(tStart);
|
|
||||||
fprintf('Total Computational Time: %0.1f seconds. \n', tEnd);
|
|
||||||
|
|
||||||
if MOT2D.DoSave
|
|
||||||
LoadingRate = struct;
|
|
||||||
LoadingRate.Values = LoadingRateArray;
|
|
||||||
MOT2D.Results = LoadingRate;
|
|
||||||
SaveFolder = [MOT2D.SaveDirectory filesep 'Results'];
|
|
||||||
Filename = ['TwoParameterScan_' datestr(now,'yyyymmdd_HHMM')];
|
|
||||||
eval([sprintf('%s_Object', Filename) ' = MOT2D;']);
|
|
||||||
mkdir(SaveFolder);
|
|
||||||
save([SaveFolder filesep Filename], sprintf('%s_Object', Filename));
|
|
||||||
end
|
|
||||||
|
|
||||||
% - Plot results
|
|
||||||
|
|
||||||
OptionsStruct = struct;
|
|
||||||
OptionsStruct.RescalingFactorForFirstParameter = (Helper.PhysicsConstants.BlueLinewidth)^-1;
|
|
||||||
OptionsStruct.XLabelString = 'Beam Detuning (\Delta/\Gamma)';
|
|
||||||
OptionsStruct.RescalingFactorForSecondParameter = 1000;
|
|
||||||
OptionsStruct.YLabelString = 'Beam Waist (mW)';
|
|
||||||
OptionsStruct.RescalingFactorForQuantityOfInterest = 1e-10;
|
|
||||||
% OptionsStruct.ZLabelString = 'Enhancement Factor (\eta)';
|
|
||||||
OptionsStruct.ZLabelString = 'Loading rate (x 10^{10} atoms/s)';
|
|
||||||
OptionsStruct.TitleString = sprintf('Magnetic Gradient = %.0f (G/cm)', MOT2D.MagneticGradient * 100);
|
|
||||||
|
|
||||||
options = Helper.convertstruct2cell(OptionsStruct);
|
|
||||||
Plotter.plotResultForTwoParameterScan(DetuningArray, BeamWaistArray, LoadingRateArray, options{:})
|
|
@ -1,33 +0,0 @@
|
|||||||
function [LoadingRateArray, StandardErrorArray, ConfidenceIntervalArray] = scanForSidebandEnhancement(ovenObj, MOTobj, CBBeamName, SBBeamName, SBDetuningArray, SBPowerArray)
|
|
||||||
|
|
||||||
Beams = MOTobj.Beams;
|
|
||||||
CoolingBeam = Beams{cellfun(@(x) strcmpi(x.Alias, CBBeamName), Beams)};
|
|
||||||
SidebandBeam = Beams{cellfun(@(x) strcmpi(x.Alias, SBBeamName), Beams)};
|
|
||||||
NumberOfPointsForFirstParam = length(SBDetuningArray);
|
|
||||||
NumberOfPointsForSecondParam = length(SBPowerArray);
|
|
||||||
LoadingRateArray = zeros(NumberOfPointsForFirstParam, NumberOfPointsForSecondParam);
|
|
||||||
StandardErrorArray = zeros(NumberOfPointsForFirstParam, NumberOfPointsForSecondParam);
|
|
||||||
ConfidenceIntervalArray = zeros(NumberOfPointsForFirstParam, NumberOfPointsForSecondParam, 2);
|
|
||||||
|
|
||||||
for i=1:NumberOfPointsForFirstParam
|
|
||||||
eval(sprintf('SidebandBeam.%s = %d;', 'Detuning', SBDetuningArray(i)));
|
|
||||||
for j=1:NumberOfPointsForSecondParam
|
|
||||||
eval(sprintf('SidebandBeam.%s = %d;', 'Power', SBPowerArray(j)));
|
|
||||||
eval(sprintf('CoolingBeam.%s = %d;', 'Power', MOTobj.TotalPower - SBPowerArray(j)));
|
|
||||||
[LoadingRateArray(i,j), StandardErrorArray(i,j), ConfidenceIntervalArray(i,j,:)] = MOTobj.runSimulation(ovenObj);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if MOTobj.DoSave
|
|
||||||
LoadingRate = struct;
|
|
||||||
LoadingRate.Values = LoadingRateArray;
|
|
||||||
LoadingRate.Errors = StandardErrorArray;
|
|
||||||
LoadingRate.CI = ConfidenceIntervalArray;
|
|
||||||
MOTobj.Results = LoadingRate;
|
|
||||||
SaveFolder = [MOTobj.SaveDirectory filesep 'Results'];
|
|
||||||
Filename = ['TwoParameterScan_' datestr(now,'yyyymmdd_HHMM')];
|
|
||||||
eval([sprintf('%s_Object', Filename) ' = MOTobj;']);
|
|
||||||
mkdir(SaveFolder);
|
|
||||||
save([SaveFolder filesep Filename], sprintf('%s_Object', Filename));
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,27 +0,0 @@
|
|||||||
function [LoadingRateArray, StandardErrorArray, ConfidenceIntervalArray] = doOneParameter(ovenObj, MOTobj, BeamName, BeamParameter, ParameterArray)
|
|
||||||
|
|
||||||
Beams = MOTobj.Beams;
|
|
||||||
Beam = Beams{cellfun(@(x) strcmpi(x.Alias, BeamName), Beams)};
|
|
||||||
NumberOfPointsForParam = length(ParameterArray);
|
|
||||||
LoadingRateArray = zeros(1,NumberOfPointsForParam);
|
|
||||||
StandardErrorArray = zeros(1,NumberOfPointsForParam);
|
|
||||||
ConfidenceIntervalArray = zeros(NumberOfPointsForParam, 2);
|
|
||||||
|
|
||||||
for i=1:NumberOfPointsForParam
|
|
||||||
eval(sprintf('Beam.%s = %d;', BeamParameter, ParameterArray(i)));
|
|
||||||
[LoadingRateArray(i), StandardErrorArray(i), ConfidenceIntervalArray(i,:)] = MOTobj.runSimulation(ovenObj);
|
|
||||||
end
|
|
||||||
|
|
||||||
if MOTobj.DoSave
|
|
||||||
LoadingRate = struct;
|
|
||||||
LoadingRate.Values = LoadingRateArray;
|
|
||||||
LoadingRate.Errors = StandardErrorArray;
|
|
||||||
LoadingRate.CI = ConfidenceIntervalArray;
|
|
||||||
MOTobj.Results = LoadingRate;
|
|
||||||
SaveFolder = [MOTobj.SaveDirectory filesep 'Results'];
|
|
||||||
Filename = ['OneParameterScan_' datestr(now,'yyyymmdd_HHMM')];
|
|
||||||
eval([sprintf('%s_Object', Filename) ' = MOTobj;']);
|
|
||||||
mkdir(SaveFolder);
|
|
||||||
save([SaveFolder filesep Filename], sprintf('%s_Object', Filename));
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,22 +0,0 @@
|
|||||||
function LoadingRateArray = doThreeParameters(ovenObj, MOTobj, BeamName, FirstBeamParameter, FirstParameterArray, ...
|
|
||||||
SecondBeamParameter, SecondParameterArray, ThirdBeamParameter, ThirdParameterArray)
|
|
||||||
|
|
||||||
NumberOfPointsForThirdParam = length(ThirdParameterArray);
|
|
||||||
LoadingRateArray = {};
|
|
||||||
|
|
||||||
for i=1:NumberOfPointsForThirdParam
|
|
||||||
eval(sprintf('MOTobj.%s = %d;', ThirdBeamParameter, ThirdParameterArray(i)));
|
|
||||||
LoadingRateArray{end+1} = Simulator.Scan.doTwoParameters(ovenObj, MOTobj, BeamName, FirstBeamParameter, FirstParameterArray, SecondBeamParameter, SecondParameterArray);
|
|
||||||
end
|
|
||||||
|
|
||||||
if MOTobj.DoSave
|
|
||||||
LoadingRate = struct;
|
|
||||||
LoadingRate.Values = LoadingRateArray;
|
|
||||||
MOTobj.Results = LoadingRate;
|
|
||||||
SaveFolder = [MOTobj.SaveDirectory filesep 'Results'];
|
|
||||||
Filename = ['ThreeParameterScan_' datestr(now,'yyyymmdd_HHMM')];
|
|
||||||
eval([sprintf('%s_Object', Filename) ' = MOTobj;']);
|
|
||||||
mkdir(SaveFolder);
|
|
||||||
save([SaveFolder filesep Filename], sprintf('%s_Object', Filename));
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,31 +0,0 @@
|
|||||||
function [LoadingRateArray, StandardErrorArray, ConfidenceIntervalArray] = doTwoParameters(ovenObj, MOTobj, BeamName, FirstBeamParameter, ...
|
|
||||||
FirstParameterArray, SecondBeamParameter, SecondParameterArray)
|
|
||||||
Beams = MOTobj.Beams;
|
|
||||||
Beam = Beams{cellfun(@(x) strcmpi(x.Alias, BeamName), Beams)};
|
|
||||||
NumberOfPointsForFirstParam = length(FirstParameterArray);
|
|
||||||
NumberOfPointsForSecondParam = length(SecondParameterArray);
|
|
||||||
LoadingRateArray = zeros(NumberOfPointsForFirstParam, NumberOfPointsForSecondParam);
|
|
||||||
StandardErrorArray = zeros(NumberOfPointsForFirstParam, NumberOfPointsForSecondParam);
|
|
||||||
ConfidenceIntervalArray = zeros(NumberOfPointsForFirstParam, NumberOfPointsForSecondParam, 2);
|
|
||||||
|
|
||||||
for i=1:NumberOfPointsForFirstParam
|
|
||||||
eval(sprintf('Beam.%s = %d;', FirstBeamParameter, FirstParameterArray(i)));
|
|
||||||
for j=1:NumberOfPointsForSecondParam
|
|
||||||
eval(sprintf('Beam.%s = %d;', SecondBeamParameter, SecondParameterArray(j)));
|
|
||||||
[LoadingRateArray(i,j), StandardErrorArray(i,j), ConfidenceIntervalArray(i,j,:)] = MOTobj.runSimulation(ovenObj);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if MOTobj.DoSave
|
|
||||||
LoadingRate = struct;
|
|
||||||
LoadingRate.Values = LoadingRateArray;
|
|
||||||
LoadingRate.Errors = StandardErrorArray;
|
|
||||||
LoadingRate.CI = ConfidenceIntervalArray;
|
|
||||||
MOTobj.Results = LoadingRate;
|
|
||||||
SaveFolder = [MOTobj.SaveDirectory filesep 'Results'];
|
|
||||||
Filename = ['TwoParameterScan_' datestr(now,'yyyymmdd_HHMM')];
|
|
||||||
eval([sprintf('%s_Object', Filename) ' = MOTobj;']);
|
|
||||||
mkdir(SaveFolder);
|
|
||||||
save([SaveFolder filesep Filename], sprintf('%s_Object', Filename));
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,203 +0,0 @@
|
|||||||
classdef Beams < handle & matlab.mixin.Copyable
|
|
||||||
|
|
||||||
properties (Access = private)
|
|
||||||
|
|
||||||
BlueBeamDefault = struct('Alias', 'Blue', ...
|
|
||||||
'Power', 400e-3, ...
|
|
||||||
'Detuning', -1.64*Helper.PhysicsConstants.BlueLinewidth, ...
|
|
||||||
'Radius', 17.5e-3, ...
|
|
||||||
'Waist', 15e-3, ...
|
|
||||||
'WaveNumber',2*pi/Helper.PhysicsConstants.BlueWavelength, ...
|
|
||||||
'Linewidth', Helper.PhysicsConstants.BlueLinewidth, ...
|
|
||||||
'SaturationIntensity', 0.1 * (2 * pi^2 / 3) * ...
|
|
||||||
((Helper.PhysicsConstants.PlanckConstantReduced * ...
|
|
||||||
Helper.PhysicsConstants.SpeedOfLight * ...
|
|
||||||
Helper.PhysicsConstants.BlueLinewidth) / (Helper.PhysicsConstants.BlueWavelength)^3));
|
|
||||||
|
|
||||||
BlueSidebandBeamDefault = struct('Alias', 'BlueSideband', ...
|
|
||||||
'Power', 400e-3, ...
|
|
||||||
'Detuning', -3*Helper.PhysicsConstants.BlueLinewidth, ...
|
|
||||||
'Radius', 17.5e-3, ...
|
|
||||||
'Waist', 15e-3, ...
|
|
||||||
'WaveNumber',2*pi/Helper.PhysicsConstants.BlueWavelength, ...
|
|
||||||
'Linewidth', Helper.PhysicsConstants.BlueLinewidth, ...
|
|
||||||
'SaturationIntensity', 0.1 * (2 * pi^2 / 3) * ...
|
|
||||||
((Helper.PhysicsConstants.PlanckConstantReduced * ...
|
|
||||||
Helper.PhysicsConstants.SpeedOfLight * ...
|
|
||||||
Helper.PhysicsConstants.BlueLinewidth) / (Helper.PhysicsConstants.BlueWavelength)^3));
|
|
||||||
|
|
||||||
PushBeamDefault = struct('Alias', 'Push', ...
|
|
||||||
'Power', 25e-3 , ...
|
|
||||||
'Detuning', 104.2*Helper.PhysicsConstants.RedLinewidth, ...
|
|
||||||
'Radius', 1.2e-03, ...
|
|
||||||
'Waist', 1.0e-03, ...
|
|
||||||
'WaveNumber',2*pi/Helper.PhysicsConstants.RedWavelength, ...
|
|
||||||
'Linewidth', Helper.PhysicsConstants.RedLinewidth, ...
|
|
||||||
'SaturationIntensity', 0.1 * (2 * pi^2 / 3) * ...
|
|
||||||
((Helper.PhysicsConstants.PlanckConstantReduced * ...
|
|
||||||
Helper.PhysicsConstants.SpeedOfLight * ...
|
|
||||||
Helper.PhysicsConstants.RedLinewidth) / (Helper.PhysicsConstants.RedWavelength)^3));
|
|
||||||
|
|
||||||
RedBeamDefault = struct('Alias', 'Red', ...
|
|
||||||
'Power', 100e-3 , ...
|
|
||||||
'Detuning', -1*Helper.PhysicsConstants.RedLinewidth, ...
|
|
||||||
'Radius', 1.2e-3, ...
|
|
||||||
'Waist', 12e-3 , ...
|
|
||||||
'WaveNumber',2*pi/Helper.PhysicsConstants.RedWavelength, ...
|
|
||||||
'Linewidth', Helper.PhysicsConstants.RedLinewidth, ...
|
|
||||||
'SaturationIntensity', 0.1 * (2 * pi^2 / 3) * ...
|
|
||||||
((Helper.PhysicsConstants.PlanckConstantReduced * ...
|
|
||||||
Helper.PhysicsConstants.SpeedOfLight * ...
|
|
||||||
Helper.PhysicsConstants.RedLinewidth) / (Helper.PhysicsConstants.RedWavelength)^3));
|
|
||||||
end
|
|
||||||
|
|
||||||
properties
|
|
||||||
Alias
|
|
||||||
Power;
|
|
||||||
Detuning;
|
|
||||||
Radius;
|
|
||||||
Waist;
|
|
||||||
WaveNumber;
|
|
||||||
SaturationIntensity;
|
|
||||||
Linewidth;
|
|
||||||
end
|
|
||||||
|
|
||||||
properties (Dependent)
|
|
||||||
SaturationParameter;
|
|
||||||
end
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
%- Methods
|
|
||||||
|
|
||||||
methods
|
|
||||||
%% Class Constructor
|
|
||||||
function this = Beams(BeamName)
|
|
||||||
input = inputParser;
|
|
||||||
addRequired(input,'BeamName', @ischar);
|
|
||||||
parse(input, BeamName);
|
|
||||||
this.Alias = input.Results.BeamName;
|
|
||||||
|
|
||||||
switch this.Alias
|
|
||||||
case this.BlueBeamDefault.Alias
|
|
||||||
this.Power = this.BlueBeamDefault.Power;
|
|
||||||
this.Detuning = this.BlueBeamDefault.Detuning;
|
|
||||||
this.Radius = this.BlueBeamDefault.Radius;
|
|
||||||
this.Waist = this.BlueBeamDefault.Waist;
|
|
||||||
this.WaveNumber = this.BlueBeamDefault.WaveNumber;
|
|
||||||
this.Linewidth = this.BlueBeamDefault.Linewidth;
|
|
||||||
this.SaturationIntensity = this.BlueBeamDefault.SaturationIntensity;
|
|
||||||
case this.BlueSidebandBeamDefault.Alias
|
|
||||||
this.Power = this.BlueSidebandBeamDefault.Power;
|
|
||||||
this.Detuning = this.BlueSidebandBeamDefault.Detuning;
|
|
||||||
this.Radius = this.BlueSidebandBeamDefault.Radius;
|
|
||||||
this.Waist = this.BlueSidebandBeamDefault.Waist;
|
|
||||||
this.WaveNumber = this.BlueSidebandBeamDefault.WaveNumber;
|
|
||||||
this.Linewidth = this.BlueSidebandBeamDefault.Linewidth;
|
|
||||||
this.SaturationIntensity = this.BlueSidebandBeamDefault.SaturationIntensity;
|
|
||||||
case this.PushBeamDefault.Alias
|
|
||||||
this.Power = this.PushBeamDefault.Power;
|
|
||||||
this.Detuning = this.PushBeamDefault.Detuning;
|
|
||||||
this.Radius = this.PushBeamDefault.Radius;
|
|
||||||
this.Waist = this.PushBeamDefault.Waist;
|
|
||||||
this.WaveNumber = this.PushBeamDefault.WaveNumber;
|
|
||||||
this.Linewidth = this.PushBeamDefault.Linewidth;
|
|
||||||
this.SaturationIntensity = this.PushBeamDefault.SaturationIntensity;
|
|
||||||
case this.RedBeamDefault.Alias
|
|
||||||
this.Power = this.RedBeamDefault.Power;
|
|
||||||
this.Detuning = this.RedBeamDefault.Detuning;
|
|
||||||
this.Radius = this.RedBeamDefault.Radius;
|
|
||||||
this.Waist = this.RedBeamDefault.Waist;
|
|
||||||
this.WaveNumber = this.RedBeamDefault.WaveNumber;
|
|
||||||
this.Linewidth = this.RedBeamDefault.Linewidth;
|
|
||||||
this.SaturationIntensity = this.RedBeamDefault.SaturationIntensity;
|
|
||||||
otherwise
|
|
||||||
error('No such beam!')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end % - lifecycle
|
|
||||||
|
|
||||||
methods
|
|
||||||
function set.Power(this,val)
|
|
||||||
this.Power = val;
|
|
||||||
end
|
|
||||||
function ret = get.Power(this)
|
|
||||||
ret = this.Power;
|
|
||||||
end
|
|
||||||
function set.Detuning(this, val)
|
|
||||||
this.Detuning = val;
|
|
||||||
end
|
|
||||||
function ret = get.Detuning(this)
|
|
||||||
ret = this.Detuning;
|
|
||||||
end
|
|
||||||
function set.Radius(this, val)
|
|
||||||
this.Radius = val;
|
|
||||||
end
|
|
||||||
function ret = get.Radius(this)
|
|
||||||
ret = this.Radius;
|
|
||||||
end
|
|
||||||
function set.Waist(this, val)
|
|
||||||
this.Waist = val;
|
|
||||||
end
|
|
||||||
function ret = get.Waist(this)
|
|
||||||
ret = this.Waist;
|
|
||||||
end
|
|
||||||
function set.WaveNumber(this, val)
|
|
||||||
this.WaveNumber = val;
|
|
||||||
end
|
|
||||||
function ret = get.WaveNumber(this)
|
|
||||||
ret = this.WaveNumber;
|
|
||||||
end
|
|
||||||
function set.SaturationIntensity(this, val)
|
|
||||||
this.SaturationIntensity = val;
|
|
||||||
end
|
|
||||||
function ret = get.SaturationIntensity(this)
|
|
||||||
ret = this.SaturationIntensity;
|
|
||||||
end
|
|
||||||
function set.Linewidth(this, val)
|
|
||||||
this.Linewidth = val;
|
|
||||||
end
|
|
||||||
function ret = get.Linewidth(this)
|
|
||||||
ret = this.Linewidth;
|
|
||||||
end
|
|
||||||
end % - setters and getters
|
|
||||||
|
|
||||||
methods
|
|
||||||
function ret = get.SaturationParameter(this)
|
|
||||||
ret = 0.1 * (8 * this.Power) / (pi*this.Waist^2 * this.SaturationIntensity); % two beams are reflected
|
|
||||||
end
|
|
||||||
end % - getters for dependent properties
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
%- Methods
|
|
||||||
|
|
||||||
methods(Access = protected)
|
|
||||||
function cp = copyElement(this)
|
|
||||||
% Shallow copy object
|
|
||||||
cp = copyElement@matlab.mixin.Copyable(this);
|
|
||||||
|
|
||||||
% Forces the setter to redefine the function handles to the new copied object
|
|
||||||
|
|
||||||
pl = properties(this);
|
|
||||||
for k = 1:length(pl)
|
|
||||||
sc = superclasses(this.(pl{k}));
|
|
||||||
if any(contains(sc,{'matlab.mixin.Copyable'}))
|
|
||||||
cp.(pl{k}) = this.(pl{k}).copy();
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
methods (Static)
|
|
||||||
|
|
||||||
% Creates an Instance of Class, ensures singleton behaviour (that there
|
|
||||||
% can only be one Instance of this class
|
|
||||||
function singleObj = getInstance(BeamName)
|
|
||||||
% Creates an Instance of Class, ensures singleton behaviour
|
|
||||||
persistent localObj;
|
|
||||||
if isempty(localObj) || ~isvalid(localObj)
|
|
||||||
localObj = Simulator.Beams(BeamName);
|
|
||||||
end
|
|
||||||
singleObj = localObj;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,173 +0,0 @@
|
|||||||
classdef MOTCaptureProcess < handle & matlab.mixin.Copyable
|
|
||||||
|
|
||||||
properties (Access = public)
|
|
||||||
SimulationMode; % MOT type
|
|
||||||
TimeStep;
|
|
||||||
SimulationTime;
|
|
||||||
NumberOfAtoms;
|
|
||||||
ErrorEstimationMethod;
|
|
||||||
|
|
||||||
%Flags
|
|
||||||
SpontaneousEmission;
|
|
||||||
SidebandBeam;
|
|
||||||
PushBeam;
|
|
||||||
Gravity;
|
|
||||||
BackgroundCollision;
|
|
||||||
|
|
||||||
DebugMode;
|
|
||||||
DoSave;
|
|
||||||
SaveDirectory;
|
|
||||||
end
|
|
||||||
|
|
||||||
properties
|
|
||||||
Beams = {}; %Contains beam objects
|
|
||||||
end % - public
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
%- Methods
|
|
||||||
|
|
||||||
methods
|
|
||||||
%% Class Destructor (Clears object)
|
|
||||||
function this = MOTCaptureProcess(varargin)
|
|
||||||
|
|
||||||
p = inputParser;
|
|
||||||
p.KeepUnmatched = true;
|
|
||||||
addParameter(p, 'SimulationMode', '2D',...
|
|
||||||
@(x) any(strcmpi(x,{'2D','3D', 'Full'})));
|
|
||||||
addParameter(p, 'ErrorEstimationMethod', 'jackknife',...
|
|
||||||
@(x) any(strcmpi(x,{'jackknife','bootstrap'})));
|
|
||||||
addParameter(p, 'NumberOfAtoms', 5000,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
|
|
||||||
addParameter(p, 'TimeStep', 10e-06,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
|
|
||||||
addParameter(p, 'SimulationTime', 3e-03,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
|
|
||||||
addParameter(p, 'SpontaneousEmission', false,...
|
|
||||||
@islogical);
|
|
||||||
addParameter(p, 'SidebandBeam', false,...
|
|
||||||
@islogical);
|
|
||||||
addParameter(p, 'PushBeam', false,...
|
|
||||||
@islogical);
|
|
||||||
addParameter(p, 'Gravity', false,...
|
|
||||||
@islogical);
|
|
||||||
addParameter(p, 'BackgroundCollision', false,...
|
|
||||||
@islogical);
|
|
||||||
addParameter(p, 'DebugMode', false,...
|
|
||||||
@islogical);
|
|
||||||
addParameter(p, 'SaveData', false,...
|
|
||||||
@islogical);
|
|
||||||
addParameter(p, 'SaveDirectory', pwd,...
|
|
||||||
@ischar);
|
|
||||||
|
|
||||||
p.parse(varargin{:});
|
|
||||||
|
|
||||||
this.SimulationMode = p.Results.SimulationMode;
|
|
||||||
this.ErrorEstimationMethod= p.Results.ErrorEstimationMethod;
|
|
||||||
|
|
||||||
this.NumberOfAtoms = p.Results.NumberOfAtoms;
|
|
||||||
this.TimeStep = p.Results.TimeStep;
|
|
||||||
this.SimulationTime = p.Results.SimulationTime;
|
|
||||||
|
|
||||||
this.SpontaneousEmission = p.Results.SpontaneousEmission;
|
|
||||||
this.SidebandBeam = p.Results.SidebandBeam;
|
|
||||||
this.PushBeam = p.Results.PushBeam;
|
|
||||||
this.Gravity = p.Results.Gravity;
|
|
||||||
this.BackgroundCollision = p.Results.BackgroundCollision;
|
|
||||||
|
|
||||||
this.DebugMode = p.Results.DebugMode;
|
|
||||||
this.DoSave = p.Results.SaveData;
|
|
||||||
this.SaveDirectory = p.Results.SaveDirectory;
|
|
||||||
|
|
||||||
switch this.SimulationMode
|
|
||||||
case "2D"
|
|
||||||
this.Beams{1} = Simulator.Beams('Blue');
|
|
||||||
this.Beams{2} = Simulator.Beams('BlueSideband');
|
|
||||||
this.Beams{3} = Simulator.Beams('Push');
|
|
||||||
case "3D"
|
|
||||||
this.Beams{1} = Simulator.Beams('Red');
|
|
||||||
% Development In progress
|
|
||||||
case "Full"
|
|
||||||
% Development In progress
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end % - lifecycle
|
|
||||||
|
|
||||||
methods
|
|
||||||
function set.TimeStep(this, val)
|
|
||||||
assert(val > 1e-06, 'Not time efficient to compute for time steps smaller than 1 microsecond!');
|
|
||||||
this.TimeStep = val;
|
|
||||||
end
|
|
||||||
function ret = get.TimeStep(this)
|
|
||||||
ret = this.TimeStep;
|
|
||||||
end
|
|
||||||
function set.SimulationTime(this, val)
|
|
||||||
% assert(val <= 5e-03, 'Not time efficient to compute for time spans longer than 5 milliseconds!');
|
|
||||||
this.SimulationTime = val;
|
|
||||||
end
|
|
||||||
function ret = get.SimulationTime(this)
|
|
||||||
ret = this.SimulationTime;
|
|
||||||
end
|
|
||||||
function set.NumberOfAtoms(this, val)
|
|
||||||
assert(val <= 50000, '!!Not time efficient to compute for atom numbers larger than 50,000!!');
|
|
||||||
this.NumberOfAtoms = val;
|
|
||||||
end
|
|
||||||
function ret = get.NumberOfAtoms(this)
|
|
||||||
ret = this.NumberOfAtoms;
|
|
||||||
end
|
|
||||||
|
|
||||||
function set.DebugMode(this, val)
|
|
||||||
this.DebugMode = val;
|
|
||||||
end
|
|
||||||
function ret = get.DebugMode(this)
|
|
||||||
ret = this.DebugMode;
|
|
||||||
end
|
|
||||||
function set.DoSave(this, val)
|
|
||||||
this.DoSave = val;
|
|
||||||
end
|
|
||||||
function ret = get.DoSave(this)
|
|
||||||
ret = this.DoSave;
|
|
||||||
end
|
|
||||||
function set.SaveDirectory(this, val)
|
|
||||||
this.SaveDirectory = val;
|
|
||||||
end
|
|
||||||
function ret = get.SaveDirectory(this)
|
|
||||||
ret = this.SaveDirectory;
|
|
||||||
end
|
|
||||||
|
|
||||||
end % - setters and getters
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
%- Methods
|
|
||||||
|
|
||||||
methods(Access = protected)
|
|
||||||
function cp = copyElement(this)
|
|
||||||
% Shallow copy object
|
|
||||||
cp = copyElement@matlab.mixin.Copyable(this);
|
|
||||||
|
|
||||||
% Forces the setter to redefine the function handles to the new copied object
|
|
||||||
|
|
||||||
pl = properties(this);
|
|
||||||
for k = 1:length(pl)
|
|
||||||
sc = superclasses(this.(pl{k}));
|
|
||||||
if any(contains(sc,{'matlab.mixin.Copyable'}))
|
|
||||||
cp.(pl{k}) = this.(pl{k}).copy();
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
methods (Static)
|
|
||||||
|
|
||||||
% Creates an Instance of Class, ensures singleton behaviour (that there
|
|
||||||
% can only be one Instance of this class
|
|
||||||
function singleObj = getInstance(varargin)
|
|
||||||
% Creates an Instance of Class, ensures singleton behaviour
|
|
||||||
persistent localObj;
|
|
||||||
if isempty(localObj) || ~isvalid(localObj)
|
|
||||||
localObj = Simulator.MOTCaptureProcess(varargin{:});
|
|
||||||
end
|
|
||||||
singleObj = localObj;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,177 +0,0 @@
|
|||||||
classdef Oven < Simulator.MOTCaptureProcess & matlab.mixin.Copyable
|
|
||||||
|
|
||||||
properties (Access = private)
|
|
||||||
|
|
||||||
OvenDefaults = struct('NozzleLength', 60e-3, ...
|
|
||||||
'NozzleRadius', 2.60e-3, ...
|
|
||||||
'OvenTemperature', 1000);
|
|
||||||
end
|
|
||||||
|
|
||||||
properties (Access = public)
|
|
||||||
NozzleLength;
|
|
||||||
NozzleRadius;
|
|
||||||
OvenTemperature;
|
|
||||||
|
|
||||||
VelocityCutoff;
|
|
||||||
ClausingFactor;
|
|
||||||
ReducedClausingFactor;
|
|
||||||
ReducedFlux;
|
|
||||||
end
|
|
||||||
|
|
||||||
properties (Dependent)
|
|
||||||
ExitDivergence;
|
|
||||||
Beta;
|
|
||||||
OvenDistance;
|
|
||||||
OvenTemperatureinKelvin;
|
|
||||||
AverageVelocity;
|
|
||||||
AtomicBeamDensity;
|
|
||||||
MeanFreePath;
|
|
||||||
CollisionTime;
|
|
||||||
end
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
%- Methods
|
|
||||||
|
|
||||||
methods
|
|
||||||
function this = Oven(varargin)
|
|
||||||
this@Simulator.MOTCaptureProcess('SimulationMode', '2D', varargin{:});
|
|
||||||
this.NozzleLength = this.OvenDefaults.NozzleLength;
|
|
||||||
this.NozzleRadius = this.OvenDefaults.NozzleRadius;
|
|
||||||
this.OvenTemperature = this.OvenDefaults.OvenTemperature;
|
|
||||||
this.ClausingFactor = this.calculateClausingFactor();
|
|
||||||
[this.ReducedClausingFactor, ~] = this.calculateReducedClausingFactor();
|
|
||||||
end
|
|
||||||
|
|
||||||
function restoreDefaults(this)
|
|
||||||
this.NozzleLength = this.OvenDefaults.NozzleLength;
|
|
||||||
this.NozzleRadius = this.OvenDefaults.NozzleRadius;
|
|
||||||
this.OvenTemperature = this.OvenDefaults.OvenTemperature;
|
|
||||||
this.ClausingFactor = this.calculateClausingFactor();
|
|
||||||
[this.ReducedClausingFactor, ~] = this.calculateReducedClausingFactor();
|
|
||||||
end
|
|
||||||
|
|
||||||
end % - lifecycle
|
|
||||||
|
|
||||||
methods
|
|
||||||
function set.NozzleLength(this,val)
|
|
||||||
this.NozzleLength = val;
|
|
||||||
end
|
|
||||||
function ret = get.NozzleLength(this)
|
|
||||||
ret = this.NozzleLength;
|
|
||||||
end
|
|
||||||
function set.NozzleRadius(this,val)
|
|
||||||
this.NozzleRadius = val;
|
|
||||||
end
|
|
||||||
function ret = get.NozzleRadius(this)
|
|
||||||
ret = this.NozzleRadius;
|
|
||||||
end
|
|
||||||
function set.OvenTemperature(this,val)
|
|
||||||
this.OvenTemperature = val;
|
|
||||||
end
|
|
||||||
function ret = get.OvenTemperature(this)
|
|
||||||
ret = this.OvenTemperature;
|
|
||||||
end
|
|
||||||
function set.VelocityCutoff(this,val)
|
|
||||||
this.VelocityCutoff = val;
|
|
||||||
end
|
|
||||||
function ret = get.VelocityCutoff(this)
|
|
||||||
ret = this.VelocityCutoff;
|
|
||||||
end
|
|
||||||
function set.ClausingFactor(this,val)
|
|
||||||
this.ClausingFactor = val;
|
|
||||||
end
|
|
||||||
function ret = get.ClausingFactor(this)
|
|
||||||
ret = this.ClausingFactor;
|
|
||||||
end
|
|
||||||
function set.ReducedClausingFactor(this,val)
|
|
||||||
this.ReducedClausingFactor = val;
|
|
||||||
end
|
|
||||||
function ret = get.ReducedClausingFactor(this)
|
|
||||||
ret = this.ReducedClausingFactor;
|
|
||||||
end
|
|
||||||
function set.ReducedFlux(this,val)
|
|
||||||
this.ReducedFlux = val;
|
|
||||||
end
|
|
||||||
function ret = get.ReducedFlux(this)
|
|
||||||
ret = this.ReducedFlux;
|
|
||||||
end
|
|
||||||
end % - setters and getters
|
|
||||||
|
|
||||||
methods
|
|
||||||
function ret = get.Beta(this)
|
|
||||||
ret = 2 * (this.NozzleRadius/this.NozzleLength);
|
|
||||||
end
|
|
||||||
|
|
||||||
function ret = get.OvenDistance(this)
|
|
||||||
ApertureCut = max(2.5e-3,this.NozzleRadius);
|
|
||||||
ret = (25+12.5)*1e-3 + (this.NozzleRadius + ApertureCut) / tan(15/360 * 2 * pi);
|
|
||||||
end
|
|
||||||
|
|
||||||
function ret = get.ExitDivergence(this)
|
|
||||||
Theta_Nozzle = atan((this.NozzleRadius + 0.035/sqrt(2))/this.OvenDistance); % The angle of capture region towards the oven nozzle
|
|
||||||
Theta_Aperture = 15/360*2*pi; % The limitation angle of the second aperture in the oven
|
|
||||||
ret = min(Theta_Nozzle,Theta_Aperture);
|
|
||||||
end
|
|
||||||
|
|
||||||
function ret = get.OvenTemperatureinKelvin(this)
|
|
||||||
ret = this.OvenTemperature + Helper.PhysicsConstants.ZeroKelvin;
|
|
||||||
end
|
|
||||||
|
|
||||||
function ret = get.AverageVelocity(this)
|
|
||||||
%See Background collision probability section in Barbiero
|
|
||||||
ret = sqrt((8 * pi * Helper.PhysicsConstants.BoltzmannConstant*this.OvenTemperatureinKelvin)/ (9 * Helper.PhysicsConstants.Dy164Mass));
|
|
||||||
end
|
|
||||||
|
|
||||||
function ret = get.AtomicBeamDensity(this)
|
|
||||||
%See Background collision probability section in Barbiero
|
|
||||||
ret = this.calculateFreeMolecularRegimeFlux / (this.AverageVelocity * pi * (this.NozzleRadius)^2);
|
|
||||||
end
|
|
||||||
|
|
||||||
function ret = get.MeanFreePath(this)
|
|
||||||
% Cross section = pi ( 2 * Van-der-waals radius of Dy)^2;
|
|
||||||
% Van-der-waals radius of Dy = 281e-12
|
|
||||||
%See Expected atomic flux section and Background collision probability section in Barbiero
|
|
||||||
ret = 1/(sqrt(2) * (pi * (2*281e-12)^2) * this.AtomicBeamDensity);
|
|
||||||
end
|
|
||||||
|
|
||||||
function ret = get.CollisionTime(this)
|
|
||||||
ret = 3 * this.MeanFreePath/this.AverageVelocity; %See Background collision probability section in Barbiero
|
|
||||||
end
|
|
||||||
|
|
||||||
end % - getters for dependent properties
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
%- Methods
|
|
||||||
|
|
||||||
methods(Access = protected)
|
|
||||||
function cp = copyElement(this)
|
|
||||||
% Shallow copy object
|
|
||||||
cp = copyElement@matlab.mixin.Copyable(this);
|
|
||||||
|
|
||||||
% Forces the setter to redefine the function handles to the new copied object
|
|
||||||
|
|
||||||
pl = properties(this);
|
|
||||||
for k = 1:length(pl)
|
|
||||||
sc = superclasses(this.(pl{k}));
|
|
||||||
if any(contains(sc,{'matlab.mixin.Copyable'}))
|
|
||||||
cp.(pl{k}) = this.(pl{k}).copy();
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
methods (Static)
|
|
||||||
|
|
||||||
% Creates an Instance of Class, ensures singleton behaviour (that there
|
|
||||||
% can only be one Instance of this class
|
|
||||||
function singleObj = getInstance(varargin)
|
|
||||||
% Creates an Instance of Class, ensures singleton behaviour
|
|
||||||
persistent localObj;
|
|
||||||
if isempty(localObj) || ~isvalid(localObj)
|
|
||||||
localObj = Simulator.Oven();
|
|
||||||
end
|
|
||||||
singleObj = localObj;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,37 +0,0 @@
|
|||||||
function ret = angularDistributionFunction(this, theta)
|
|
||||||
%This function calculate the angle distribution of atoms coming out
|
|
||||||
%from a single channel.
|
|
||||||
|
|
||||||
KnudsenNumber = this.MeanFreePath/this.NozzleLength;
|
|
||||||
|
|
||||||
alpha = 0.5 - (3*this.Beta^2)^-1 * ...
|
|
||||||
((1 - (2*this.Beta^3) + ((2*this.Beta^2) - 1) * sqrt(1+this.Beta^2)) / ...
|
|
||||||
(sqrt(1+this.Beta^2) - (this.Beta^2 * asinh((this.Beta^2)^-1))));
|
|
||||||
|
|
||||||
eta0 = alpha;
|
|
||||||
eta1 = 1 - alpha;
|
|
||||||
|
|
||||||
delta = (eta0./sqrt(2*KnudsenNumber*(eta1-eta0)))./sqrt(cos(theta));
|
|
||||||
|
|
||||||
F = 2/sqrt(pi)* (1-eta1)/eta0 * delta.* exp( -(delta*eta1/eta0).^2 );
|
|
||||||
q = this.Beta^-1 * tan(theta);
|
|
||||||
R = acos(q) - (q .* sqrt(1-q.^2));
|
|
||||||
|
|
||||||
if abs(q) >= 1
|
|
||||||
t = linspace(0,1,10000);
|
|
||||||
S = sum(sqrt(1-t.^2).* ( erf(delta.*(1 + (t.*(eta1-eta0)./(q.*eta0)) ))-erf(delta)))*(t(2)-t(1));
|
|
||||||
if S == 0 || isnan(S)
|
|
||||||
ret = eta0*cos(theta);
|
|
||||||
else
|
|
||||||
ret = eta0*cos(theta)+ 2/sqrt(pi)*eta0*cos(theta) * (exp(delta.^2)/delta) * S;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
t = linspace(0,q,10000);
|
|
||||||
S = sum(sqrt(1-t.^2).* ( erf(delta.*(1 + (t.*(eta1-eta0)./(q.*eta0)) ))-erf(delta)))*(t(2)-t(1));
|
|
||||||
if isnan(S)
|
|
||||||
S=0;
|
|
||||||
end
|
|
||||||
ret = 2/sqrt(pi)*eta0*cos(theta)*(exp(delta.^2)/delta) * (R./2*(erf(delta*eta1/eta0)-erf(delta)+F)+S)+eta0*cos(theta);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
|||||||
function ret = calculateClausingFactor(this)
|
|
||||||
|
|
||||||
ClausingFactorApproximation = (8 * this.NozzleRadius) / (3 * this.NozzleLength);
|
|
||||||
|
|
||||||
alpha = 0.5 - (3*this.Beta^2)^-1 * ((1 - (2*this.Beta^3) + ((2*this.Beta^2) - 1) * sqrt(1+this.Beta^2)) / (sqrt(1+this.Beta^2) - (this.Beta^2 * asinh((this.Beta^2)^-1))));
|
|
||||||
ClausingFactorAnalytic = 1 + (2/3) * (1 - (2 * alpha)) * (this.Beta - sqrt(1 - this.Beta^2)) + (2/3) * (1 + alpha) * this.Beta^(-2) * (1 - sqrt(1 + this.Beta^2));
|
|
||||||
|
|
||||||
ret = ClausingFactorApproximation;
|
|
||||||
end
|
|
@ -1,11 +0,0 @@
|
|||||||
function ret = calculateFreeMolecularRegimeFlux(this)
|
|
||||||
%This function calculate the total flux of atoms coming out from a tube
|
|
||||||
%See Expected atomic flux section in Barbiero
|
|
||||||
Dy164VapourPressure = 133.322*exp(11.4103-2.3785e+04./(-219.4821+this.OvenTemperatureinKelvin)).*100; % Vapor Pressure Dysprosium for the given oven temperature
|
|
||||||
Dy164DensityinOven = Dy164VapourPressure/(Helper.PhysicsConstants.BoltzmannConstant*this.OvenTemperatureinKelvin);
|
|
||||||
ret = 1/4 * Dy164DensityinOven * this.AverageVelocity * pi * this.NozzleRadius.^2;
|
|
||||||
% Removed the Helper.PhysicsConstants.Dy164IsotopicAbundance multiplication
|
|
||||||
% Needs to be multiplied with the "Clausing Factor" which here would be
|
|
||||||
% the probability not for the full solid angle but the angle subtended
|
|
||||||
% by the aperture of the oven at its mouth.
|
|
||||||
end
|
|
@ -1,17 +0,0 @@
|
|||||||
function [ReducedClausingFactor, NormalizationConstantForAngularDistribution] = calculateReducedClausingFactor(this)
|
|
||||||
ThetaArray = linspace(0.0001, pi/2, 1000);
|
|
||||||
AngularDistribution = zeros(1,length(ThetaArray));
|
|
||||||
parfor k = 1:length(ThetaArray)
|
|
||||||
AngularDistribution(k) = this.angularDistributionFunction(ThetaArray(k));
|
|
||||||
end
|
|
||||||
|
|
||||||
NormalizationConstantForAngularDistribution = max(2 * pi .* sin(ThetaArray) .* AngularDistribution);
|
|
||||||
|
|
||||||
ReducedClausingFactor = 0; % We have to calculate the probability of an atom coming out of the oven subject to the physical constraint
|
|
||||||
parfor p = 1:length(ThetaArray) % that the angle of divergence is not more than the angle subtended at the mouth of the nozzle
|
|
||||||
if ThetaArray(p) <= this.ExitDivergence
|
|
||||||
ReducedClausingFactor = ReducedClausingFactor + (2 * pi * sin(ThetaArray(p)) * AngularDistribution(p) * (ThetaArray(2)-ThetaArray(1)));
|
|
||||||
end
|
|
||||||
end
|
|
||||||
ReducedClausingFactor = ReducedClausingFactor / pi;
|
|
||||||
end
|
|
@ -1,7 +0,0 @@
|
|||||||
function ret = initialPositionSampling(this)
|
|
||||||
n = this.NumberOfAtoms;
|
|
||||||
phi = 2 * pi * rand(n,1);
|
|
||||||
rho = this.Beta * 0.5 * this.NozzleLength * sqrt(rand(n,1));
|
|
||||||
ret = [-this.OvenDistance * ones(n,1), rho.*cos(phi), rho.*sin(phi)];
|
|
||||||
end
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
|||||||
function ret = initialVelocitySampling(this, MOTObj)
|
|
||||||
n = this.NumberOfAtoms;
|
|
||||||
% Calculate Calculate Capture velocity --> Introduce velocity cutoff
|
|
||||||
MOTObj.CaptureVelocity = MOTObj.calculateCaptureVelocity(this, [-this.OvenDistance,0,0], [1,0,0]);
|
|
||||||
this.VelocityCutoff = 1.05 * MOTObj.CaptureVelocity(1); % Should be the magnitude of the 3-D velocity vector but since here the obtained capture
|
|
||||||
% velocity is only along the x-axis, we take the first term which is the x-component of the velocity.
|
|
||||||
|
|
||||||
[ReducedClausingFactor, NormalizationConstantForAngularDistribution] = this.calculateReducedClausingFactor();
|
|
||||||
this.ReducedClausingFactor = ReducedClausingFactor;
|
|
||||||
|
|
||||||
VelocityDistribution = @(velocity) sqrt(2 / pi) * sqrt(Helper.PhysicsConstants.Dy164Mass/(Helper.PhysicsConstants.BoltzmannConstant * this.OvenTemperatureinKelvin))^3 ...
|
|
||||||
* velocity.^3 .* exp(-velocity.^2 .* (Helper.PhysicsConstants.Dy164Mass / (2 * Helper.PhysicsConstants.BoltzmannConstant ...
|
|
||||||
* this.OvenTemperatureinKelvin)));
|
|
||||||
|
|
||||||
c = integral(VelocityDistribution, 0, this.VelocityCutoff) / integral(VelocityDistribution, 0, inf);
|
|
||||||
|
|
||||||
this.ReducedFlux = c * this.ReducedClausingFactor * this.calculateFreeMolecularRegimeFlux();
|
|
||||||
|
|
||||||
ret = zeros(n,3);
|
|
||||||
SampledVelocityMagnitude = zeros(n,1);
|
|
||||||
SampledPolarAngle = zeros(n,1);
|
|
||||||
SampledAzimuthalAngle = zeros(n,1);
|
|
||||||
|
|
||||||
MostProbableVelocity = sqrt((3 * Helper.PhysicsConstants.BoltzmannConstant * this.OvenTemperature) / Helper.PhysicsConstants.Dy164Mass); % For v * f(v) distribution
|
|
||||||
|
|
||||||
if MostProbableVelocity > this.VelocityCutoff
|
|
||||||
MaximumVelocityAllowed = this.VelocityCutoff;
|
|
||||||
else
|
|
||||||
MaximumVelocityAllowed = MostProbableVelocity;
|
|
||||||
end
|
|
||||||
NormalizationConstantForVelocityDistribution = this.velocityDistributionFunction(MaximumVelocityAllowed);
|
|
||||||
|
|
||||||
parfor i = 1:n
|
|
||||||
% Rejection Sampling of speed
|
|
||||||
y = rand(1);
|
|
||||||
x = this.VelocityCutoff * rand(1);
|
|
||||||
while y > ((NormalizationConstantForVelocityDistribution)^-1 * this.velocityDistributionFunction(x)) %As long as this loop condition is satisfied, reject the corresponding x value
|
|
||||||
y = rand(1);
|
|
||||||
x = this.VelocityCutoff * rand(1);
|
|
||||||
end
|
|
||||||
SampledVelocityMagnitude(i) = x; % When loop condition is not satisfied, accept x value and store as sample
|
|
||||||
|
|
||||||
% Rejection Sampling of polar angle
|
|
||||||
w = rand(1);
|
|
||||||
z = this.ExitDivergence * rand(1);
|
|
||||||
|
|
||||||
while w > ((NormalizationConstantForAngularDistribution)^-1 * 2 * pi * this.angularDistributionFunction(z) * sin(z)) %As long as this loop condition is satisfied, reject the corresponding x value
|
|
||||||
w = rand(1);
|
|
||||||
z = this.ExitDivergence * rand(1);
|
|
||||||
end
|
|
||||||
SampledPolarAngle(i) = z; %When loop condition is not satisfied, accept x value and store as sample
|
|
||||||
|
|
||||||
% Sampling of azimuthal angle
|
|
||||||
SampledAzimuthalAngle(i)= 2 * pi * rand(1);
|
|
||||||
|
|
||||||
ret(i,:)=[SampledVelocityMagnitude(i)*cos(SampledPolarAngle(i)), SampledVelocityMagnitude(i)*sin(SampledPolarAngle(i))*cos(SampledAzimuthalAngle(i)), ...
|
|
||||||
SampledVelocityMagnitude(i)*sin(SampledPolarAngle(i))*sin(SampledAzimuthalAngle(i))];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
|||||||
function ret = velocityDistributionFunction(this, velocity)
|
|
||||||
ret = sqrt(2 / pi) * sqrt(Helper.PhysicsConstants.Dy164Mass/(Helper.PhysicsConstants.BoltzmannConstant * this.OvenTemperatureinKelvin))^3 ...
|
|
||||||
* velocity^3 * exp(-velocity^2.*(Helper.PhysicsConstants.Dy164Mass / (2 * Helper.PhysicsConstants.BoltzmannConstant ...
|
|
||||||
* this.OvenTemperatureinKelvin)));
|
|
||||||
end
|
|
@ -1,191 +0,0 @@
|
|||||||
classdef TwoDimensionalMOT < Simulator.MOTCaptureProcess & matlab.mixin.Copyable
|
|
||||||
|
|
||||||
properties (Access = private)
|
|
||||||
MagneticGradienDefault = 0.40; % T/m
|
|
||||||
ExitDivergenceDefault = 15e-3;
|
|
||||||
DistanceBetweenPushBeamAnd3DMOTCenterDefault = 0;
|
|
||||||
PushBeamDistanceDefault = 0.32;
|
|
||||||
end
|
|
||||||
|
|
||||||
properties (Access = public)
|
|
||||||
TotalPower;
|
|
||||||
LandegFactor;
|
|
||||||
MagneticSubLevel;
|
|
||||||
MagneticGradient;
|
|
||||||
CaptureVelocity;
|
|
||||||
ExitDivergence;
|
|
||||||
DistanceBetweenPushBeamAnd3DMOTCenter;
|
|
||||||
PushBeamDistance;
|
|
||||||
TimeSpentInInteractionRegion;
|
|
||||||
ParticleDynamicalQuantities;
|
|
||||||
InitialParameters;
|
|
||||||
BootstrapSampleLength;
|
|
||||||
BootstrapSampleNumber;
|
|
||||||
Results;
|
|
||||||
end
|
|
||||||
|
|
||||||
methods
|
|
||||||
function this = TwoDimensionalMOT(varargin)
|
|
||||||
this@Simulator.MOTCaptureProcess('SimulationMode', '2D', varargin{:});
|
|
||||||
p = inputParser;
|
|
||||||
p.KeepUnmatched = true;
|
|
||||||
addParameter(p, 'TotalPower', 0.8,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
|
|
||||||
addParameter(p, 'LandegFactor', 1,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x) && (x > 0)));
|
|
||||||
addParameter(p, 'MagneticSubLevel', 1,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x)));
|
|
||||||
addParameter(p, 'MagneticGradient', 0.38,...
|
|
||||||
@(x) assert(isnumeric(x) && isscalar(x)));
|
|
||||||
|
|
||||||
p.parse(varargin{:});
|
|
||||||
|
|
||||||
this.TotalPower = p.Results.TotalPower;
|
|
||||||
this.LandegFactor = p.Results.LandegFactor;
|
|
||||||
this.MagneticSubLevel = p.Results.MagneticSubLevel;
|
|
||||||
this.MagneticGradient = p.Results.MagneticGradient;
|
|
||||||
this.ExitDivergence = this.ExitDivergenceDefault;
|
|
||||||
this.DistanceBetweenPushBeamAnd3DMOTCenter = this.DistanceBetweenPushBeamAnd3DMOTCenterDefault;
|
|
||||||
this.PushBeamDistance = this.PushBeamDistanceDefault;
|
|
||||||
this.InitialParameters = struct;
|
|
||||||
this.InitialParameters.TotalPower = this.TotalPower;
|
|
||||||
this.InitialParameters.LandegFactor = this.LandegFactor;
|
|
||||||
this.InitialParameters.MagneticSubLevel= this.MagneticSubLevel;
|
|
||||||
this.InitialParameters.MagneticGradient= this.MagneticGradient;
|
|
||||||
this.BootstrapSampleLength = 0.5 * this.NumberOfAtoms;
|
|
||||||
this.BootstrapSampleNumber = 1000;
|
|
||||||
end
|
|
||||||
|
|
||||||
function restoreDefaults(this)
|
|
||||||
this.TotalPower = this.InitialParameters.TotalPower;
|
|
||||||
this.LandegFactor = this.InitialParameters.LandegFactor;
|
|
||||||
this.MagneticSubLevel = this.InitialParameters.MagneticSubLevel;
|
|
||||||
this.MagneticGradient = this.InitialParameters.MagneticGradient;
|
|
||||||
this.ExitDivergence = this.ExitDivergenceDefault;
|
|
||||||
this.DistanceBetweenPushBeamAnd3DMOTCenter = this.DistanceBetweenPushBeamAnd3DMOTCenterDefault;
|
|
||||||
this.PushBeamDistance = this.PushBeamDistanceDefault;
|
|
||||||
end
|
|
||||||
end % - lifecycle
|
|
||||||
|
|
||||||
methods
|
|
||||||
function set.TotalPower(this,val)
|
|
||||||
this.TotalPower = val;
|
|
||||||
end
|
|
||||||
function ret = get.TotalPower(this)
|
|
||||||
ret = this.TotalPower;
|
|
||||||
end
|
|
||||||
function set.LandegFactor(this,val)
|
|
||||||
this.LandegFactor = val;
|
|
||||||
end
|
|
||||||
function ret = get.LandegFactor(this)
|
|
||||||
ret = this.LandegFactor;
|
|
||||||
end
|
|
||||||
function set.MagneticSubLevel(this,val)
|
|
||||||
this.MagneticSubLevel = val;
|
|
||||||
end
|
|
||||||
function ret = get.MagneticSubLevel(this)
|
|
||||||
ret = this.MagneticSubLevel;
|
|
||||||
end
|
|
||||||
function set.MagneticGradient(this,val)
|
|
||||||
this.MagneticGradient = val;
|
|
||||||
end
|
|
||||||
function ret = get.MagneticGradient(this)
|
|
||||||
ret = this.MagneticGradient;
|
|
||||||
end
|
|
||||||
function set.CaptureVelocity(this,val)
|
|
||||||
this.CaptureVelocity = val;
|
|
||||||
end
|
|
||||||
function ret = get.CaptureVelocity(this)
|
|
||||||
ret = this.CaptureVelocity;
|
|
||||||
end
|
|
||||||
function set.ExitDivergence(this,val)
|
|
||||||
this.ExitDivergence = val;
|
|
||||||
end
|
|
||||||
function ret = get.ExitDivergence(this)
|
|
||||||
ret = this.ExitDivergence;
|
|
||||||
end
|
|
||||||
function set.DistanceBetweenPushBeamAnd3DMOTCenter(this,val)
|
|
||||||
this.DistanceBetweenPushBeamAnd3DMOTCenter = val;
|
|
||||||
end
|
|
||||||
function ret = get.DistanceBetweenPushBeamAnd3DMOTCenter(this)
|
|
||||||
ret = this.DistanceBetweenPushBeamAnd3DMOTCenter;
|
|
||||||
end
|
|
||||||
function set.PushBeamDistance(this,val)
|
|
||||||
this.PushBeamDistance = val;
|
|
||||||
end
|
|
||||||
function ret = get.PushBeamDistance(this)
|
|
||||||
ret = this.PushBeamDistance;
|
|
||||||
end
|
|
||||||
function set.TimeSpentInInteractionRegion(this,val)
|
|
||||||
this.TimeSpentInInteractionRegion = val;
|
|
||||||
end
|
|
||||||
function ret = get.TimeSpentInInteractionRegion(this)
|
|
||||||
ret = this.TimeSpentInInteractionRegion;
|
|
||||||
end
|
|
||||||
function set.ParticleDynamicalQuantities(this,val)
|
|
||||||
this.ParticleDynamicalQuantities = val;
|
|
||||||
end
|
|
||||||
function ret = get.ParticleDynamicalQuantities(this)
|
|
||||||
ret = this.ParticleDynamicalQuantities;
|
|
||||||
end
|
|
||||||
function set.InitialParameters(this,val)
|
|
||||||
this.InitialParameters = val;
|
|
||||||
end
|
|
||||||
function ret = get.InitialParameters(this)
|
|
||||||
ret = this.InitialParameters;
|
|
||||||
end
|
|
||||||
function set.BootstrapSampleLength(this,val)
|
|
||||||
this.BootstrapSampleLength = val;
|
|
||||||
end
|
|
||||||
function ret = get.BootstrapSampleLength(this)
|
|
||||||
ret = this.BootstrapSampleLength;
|
|
||||||
end
|
|
||||||
function set.BootstrapSampleNumber(this,val)
|
|
||||||
this.BootstrapSampleNumber = val;
|
|
||||||
end
|
|
||||||
function ret = get.BootstrapSampleNumber(this)
|
|
||||||
ret = this.BootstrapSampleNumber;
|
|
||||||
end
|
|
||||||
function set.Results(this, val)
|
|
||||||
this.Results = val;
|
|
||||||
end
|
|
||||||
function ret = get.Results(this)
|
|
||||||
ret = this.Results;
|
|
||||||
end
|
|
||||||
end % - setters and getters
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
%- Methods
|
|
||||||
|
|
||||||
methods(Access = protected)
|
|
||||||
function cp = copyElement(this)
|
|
||||||
% Shallow copy object
|
|
||||||
cp = copyElement@matlab.mixin.Copyable(this);
|
|
||||||
|
|
||||||
% Forces the setter to redefine the function handles to the new copied object
|
|
||||||
|
|
||||||
pl = properties(this);
|
|
||||||
for k = 1:length(pl)
|
|
||||||
sc = superclasses(this.(pl{k}));
|
|
||||||
if any(contains(sc,{'matlab.mixin.Copyable'}))
|
|
||||||
cp.(pl{k}) = this.(pl{k}).copy();
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
methods (Static)
|
|
||||||
|
|
||||||
% Creates an Instance of Class, ensures singleton behaviour (that there
|
|
||||||
% can only be one Instance of this class
|
|
||||||
function singleObj = getInstance(varargin)
|
|
||||||
% Creates an Instance of Class, ensures singleton behaviour
|
|
||||||
persistent localObj;
|
|
||||||
if isempty(localObj) || ~isvalid(localObj)
|
|
||||||
localObj = Simulator.TwoDimensionalMOT(varargin{:});
|
|
||||||
end
|
|
||||||
singleObj = localObj;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,35 +0,0 @@
|
|||||||
function ret = accelerationDueToPushBeam(this, PositionVector, VelocityVector)
|
|
||||||
% is the distance between the chamber center and the cross point of push beam and z-axis (along the gravity)
|
|
||||||
WaveVectorEndPoint = [0, 1, this.DistanceBetweenPushBeamAnd3DMOTCenter/this.PushBeamDistance];
|
|
||||||
WaveVectorEndPoint = WaveVectorEndPoint./norm(WaveVectorEndPoint);
|
|
||||||
Origin=[0,0,0];
|
|
||||||
|
|
||||||
PushBeamObj = this.Beams{cellfun(@(x) strcmpi(x.Alias, 'Push'), this.Beams)};
|
|
||||||
PushBeamDetuning = PushBeamObj.Detuning;
|
|
||||||
PushBeamRadius = PushBeamObj.Radius;
|
|
||||||
PushBeamWaist = PushBeamObj.Waist;
|
|
||||||
PushBeamWaveNumber = PushBeamObj.WaveNumber;
|
|
||||||
PushBeamLinewidth = PushBeamObj.Linewidth;
|
|
||||||
PushBeamSaturationParameter = 0.25 * PushBeamObj.SaturationParameter;
|
|
||||||
|
|
||||||
SaturationIntensity = this.calculateLocalSaturationIntensity(PushBeamSaturationParameter, PositionVector, Origin, WaveVectorEndPoint, PushBeamRadius, PushBeamWaist);
|
|
||||||
|
|
||||||
DopplerShift = dot(WaveVectorEndPoint(:), VelocityVector) * PushBeamWaveNumber;
|
|
||||||
|
|
||||||
Detuning = PushBeamDetuning - DopplerShift;
|
|
||||||
|
|
||||||
s_push = SaturationIntensity/(1 + SaturationIntensity + (4 * (Detuning./PushBeamLinewidth).^2));
|
|
||||||
a_sat = (Helper.PhysicsConstants.PlanckConstantReduced * PushBeamWaveNumber * WaveVectorEndPoint(:)/Helper.PhysicsConstants.Dy164Mass).*(PushBeamLinewidth * 0.5);
|
|
||||||
a_push = a_sat .* (s_push/(1+s_push));
|
|
||||||
|
|
||||||
if this.SpontaneousEmission
|
|
||||||
a_scatter = this.accelerationDueToSpontaneousEmissionProcess(s_push, s_push, PushBeamLinewidth, PushBeamWaveNumber);
|
|
||||||
else
|
|
||||||
a_scatter = [0,0,0];
|
|
||||||
end
|
|
||||||
|
|
||||||
a_total = a_push + a_scatter;
|
|
||||||
|
|
||||||
ret = a_total(1:3);
|
|
||||||
end
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
|||||||
function ret = accelerationDueToSpontaneousEmissionProcess(this, SaturationParameter, TotalSaturationParameter, Linewidth, WaveNumber)
|
|
||||||
Vector = [2*rand(1)-1,2*rand(1)-1,2*rand(1)-1];
|
|
||||||
Vector = Vector./norm(Vector);
|
|
||||||
|
|
||||||
ScatteringRate = (0.5 * Linewidth) * (SaturationParameter / (1 + TotalSaturationParameter));
|
|
||||||
NumberOfScatteringEvents = floor(ScatteringRate * this.TimeStep);
|
|
||||||
|
|
||||||
if NumberOfScatteringEvents > 0
|
|
||||||
ret = Vector.*((Helper.PhysicsConstants.PlanckConstantReduced * WaveNumber) / ...
|
|
||||||
(Helper.PhysicsConstants.Dy164Mass * this.TimeStep)).* sqrt(NumberOfScatteringEvents);
|
|
||||||
else
|
|
||||||
ret = zeros(1,3);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
|||||||
function [LoadingRate, StandardError, ConfidenceInterval] = bootstrapErrorEstimation(this, ovenObj, NumberOfLoadedAtoms)
|
|
||||||
n = this.NumberOfAtoms;
|
|
||||||
SampleLength = this.BootstrapSampleLength;
|
|
||||||
NumberOfBootsrapSamples = this.BootstrapSampleNumber;
|
|
||||||
MeanCaptureRatioInEachSample = zeros(1,NumberOfBootsrapSamples);
|
|
||||||
for SampleNumber = 1:NumberOfBootsrapSamples
|
|
||||||
BoostrapSample = datasample(NumberOfLoadedAtoms, SampleLength); % Sample with replacement
|
|
||||||
MeanCaptureRatioInEachSample(SampleNumber) = mean(BoostrapSample) / n; % Empirical bootstrap distribution of sample means
|
|
||||||
end
|
|
||||||
|
|
||||||
LoadingRate = mean(MeanCaptureRatioInEachSample) * ovenObj.ReducedFlux;
|
|
||||||
|
|
||||||
Variance = 0; % Bootstrap Estimate of Variance
|
|
||||||
for SampleNumber = 1:NumberOfBootsrapSamples
|
|
||||||
Variance = Variance + (MeanCaptureRatioInEachSample(SampleNumber) - mean(MeanCaptureRatioInEachSample))^2;
|
|
||||||
end
|
|
||||||
|
|
||||||
StandardError = sqrt((1 / (NumberOfBootsrapSamples-1)) * Variance) * ovenObj.ReducedFlux;
|
|
||||||
|
|
||||||
ts = tinv([0.025 0.975],NumberOfBootsrapSamples-1); % T-Score
|
|
||||||
ConfidenceInterval = LoadingRate + ts*StandardError; % 95% Confidence Intervals
|
|
||||||
end
|
|
@ -1,22 +0,0 @@
|
|||||||
function ret = calculateCaptureVelocity(this, ovenObj, PositionVector, VelocityVector)
|
|
||||||
VelocityUnitVector = VelocityVector./norm(VelocityVector);
|
|
||||||
UpperLimit = 500;
|
|
||||||
LowerLimit = 0;
|
|
||||||
|
|
||||||
for Index = 1:500
|
|
||||||
InitialVelocity = (0.5 * (UpperLimit + LowerLimit)) * VelocityUnitVector;
|
|
||||||
ParticleDynamicalQuantities = this.solver(PositionVector, InitialVelocity);
|
|
||||||
FinalPositionVector = ParticleDynamicalQuantities(end, 1:3);
|
|
||||||
if rssq(FinalPositionVector) <= ovenObj.OvenDistance
|
|
||||||
LowerLimit = 0.5 * (UpperLimit + LowerLimit);
|
|
||||||
else
|
|
||||||
UpperLimit = 0.5 * (UpperLimit + LowerLimit);
|
|
||||||
end
|
|
||||||
|
|
||||||
if UpperLimit - LowerLimit < 1
|
|
||||||
ret = (0.5 * (UpperLimit + LowerLimit)) * VelocityUnitVector;
|
|
||||||
break;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
|||||||
function [LoadingRate, StandardError, ConfidenceInterval] = calculateLoadingRate(this, ovenObj)
|
|
||||||
n = this.NumberOfAtoms;
|
|
||||||
DynamicalQuantities = this.ParticleDynamicalQuantities;
|
|
||||||
CollisionEvents = zeros(1, n);
|
|
||||||
NumberOfLoadedAtoms = zeros(1, n);
|
|
||||||
|
|
||||||
|
|
||||||
% Include the stochastic process of background collisions
|
|
||||||
for AtomIndex = 1:n
|
|
||||||
this.TimeSpentInInteractionRegion(AtomIndex) = this.computeTimeSpentInInteractionRegion(squeeze(DynamicalQuantities(AtomIndex,:,1:3)));
|
|
||||||
CollisionEvents(AtomIndex) = this.computeCollisionProbability(ovenObj, this.TimeSpentInInteractionRegion(AtomIndex));
|
|
||||||
end
|
|
||||||
|
|
||||||
% Count the number of loaded atoms subject to conditions
|
|
||||||
|
|
||||||
switch this.ErrorEstimationMethod
|
|
||||||
case 'bootstrap'
|
|
||||||
NumberOfTimeSteps = int64(this.SimulationTime/this.TimeStep);
|
|
||||||
NumberOfLoadedAtoms = zeros(1, NumberOfTimeSteps);
|
|
||||||
LoadedAtomIndices = [];
|
|
||||||
for TimeIndex = 1:NumberOfTimeSteps
|
|
||||||
if TimeIndex ~= 1
|
|
||||||
NumberOfLoadedAtoms(TimeIndex) = NumberOfLoadedAtoms(TimeIndex-1);
|
|
||||||
end
|
|
||||||
for AtomIndex = 1:n
|
|
||||||
Position = squeeze(DynamicalQuantities(AtomIndex, TimeIndex, 1:3))';
|
|
||||||
if this.exitCondition(Position, CollisionEvents(AtomIndex))
|
|
||||||
if ~ismember(AtomIndex, LoadedAtomIndices)
|
|
||||||
NumberOfLoadedAtoms(TimeIndex) = NumberOfLoadedAtoms(TimeIndex) + 1;
|
|
||||||
LoadedAtomIndices(end+1) = AtomIndex;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if ismember(AtomIndex, LoadedAtomIndices)
|
|
||||||
NumberOfLoadedAtoms(TimeIndex) = NumberOfLoadedAtoms(TimeIndex) - 1;
|
|
||||||
LoadedAtomIndices(LoadedAtomIndices==AtomIndex) = [];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
[LoadingRate, StandardError, ConfidenceInterval] = this.bootstrapErrorEstimation(ovenObj, NumberOfLoadedAtoms);
|
|
||||||
case 'jackknife'
|
|
||||||
for AtomIndex = 1:n
|
|
||||||
if AtomIndex ~= 1
|
|
||||||
NumberOfLoadedAtoms(AtomIndex) = NumberOfLoadedAtoms(AtomIndex-1);
|
|
||||||
end
|
|
||||||
Position = squeeze(DynamicalQuantities(AtomIndex, end, 1:3))';
|
|
||||||
if this.exitCondition(Position, CollisionEvents(AtomIndex))
|
|
||||||
NumberOfLoadedAtoms(AtomIndex) = NumberOfLoadedAtoms(AtomIndex) + 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
[LoadingRate, StandardError, ConfidenceInterval] = jackknifeErrorEstimation(this, ovenObj, NumberOfLoadedAtoms);
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,10 +0,0 @@
|
|||||||
function ret = calculateLocalSaturationIntensity(~, PeakIntensity, PositionVector, WaveVectorOrigin, WaveVectorEndPoint, BeamRadius, BeamWaist)
|
|
||||||
|
|
||||||
DistanceBetweenAtomAndLaserBeamAxis = Helper.calculateDistanceFromPointToLine(PositionVector, WaveVectorOrigin, WaveVectorEndPoint);
|
|
||||||
|
|
||||||
if DistanceBetweenAtomAndLaserBeamAxis <= BeamRadius
|
|
||||||
ret = PeakIntensity * exp(-2*DistanceBetweenAtomAndLaserBeamAxis^2 / BeamWaist^2);
|
|
||||||
else
|
|
||||||
ret = 0;
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,104 +0,0 @@
|
|||||||
function ret = calculateTotalAcceleration(this, PositionVector, VelocityVector)
|
|
||||||
CoolingBeamObj = this.Beams{cellfun(@(x) strcmpi(x.Alias, 'Blue'), this.Beams)};
|
|
||||||
CoolingBeamDetuning = CoolingBeamObj.Detuning;
|
|
||||||
CoolingBeamRadius = CoolingBeamObj.Radius;
|
|
||||||
CoolingBeamWaist = CoolingBeamObj.Waist;
|
|
||||||
CoolingBeamWaveNumber = CoolingBeamObj.WaveNumber;
|
|
||||||
CoolingBeamLinewidth = CoolingBeamObj.Linewidth;
|
|
||||||
CoolingBeamSaturationParameter = CoolingBeamObj.SaturationParameter;
|
|
||||||
|
|
||||||
SidebandBeamObj = this.Beams{cellfun(@(x) strcmpi(x.Alias, 'BlueSideband'), this.Beams)};
|
|
||||||
SidebandDetuning = SidebandBeamObj.Detuning;
|
|
||||||
SidebandBeamRadius = SidebandBeamObj.Radius;
|
|
||||||
SidebandBeamWaist = SidebandBeamObj.Waist;
|
|
||||||
SidebandSaturationParameter = SidebandBeamObj.SaturationParameter;
|
|
||||||
|
|
||||||
WaveVectorEndPoint = zeros(2,3);
|
|
||||||
WaveVectorEndPoint(1,:) = [1,0,1];
|
|
||||||
WaveVectorEndPoint(1,:) = WaveVectorEndPoint(1,1:3)/norm(WaveVectorEndPoint(1,:));
|
|
||||||
WaveVectorEndPoint(2,:) = [-1,0,1];
|
|
||||||
WaveVectorEndPoint(2,:) = WaveVectorEndPoint(2,1:3)/norm(WaveVectorEndPoint(2,:));
|
|
||||||
|
|
||||||
Sigma = [1,-1];
|
|
||||||
Origin = [0,0,0];
|
|
||||||
|
|
||||||
% Calculate the Saturation Intensity at the specified point along its Gaussian Profile
|
|
||||||
CoolingBeamLocalSaturationIntensity = [this.calculateLocalSaturationIntensity(0.25 * CoolingBeamSaturationParameter, PositionVector, Origin, WaveVectorEndPoint(1,:), CoolingBeamRadius, CoolingBeamWaist), ...
|
|
||||||
this.calculateLocalSaturationIntensity(0.25 * CoolingBeamSaturationParameter, PositionVector, Origin, WaveVectorEndPoint(2,:), CoolingBeamRadius, CoolingBeamWaist)];
|
|
||||||
|
|
||||||
SidebandLocalSaturationIntensity = [this.calculateLocalSaturationIntensity(0.25 * SidebandSaturationParameter, PositionVector, Origin, WaveVectorEndPoint(1,:), SidebandBeamRadius, SidebandBeamWaist), ...
|
|
||||||
this.calculateLocalSaturationIntensity(0.25 * SidebandSaturationParameter, PositionVector, Origin, WaveVectorEndPoint(2,:), SidebandBeamRadius, SidebandBeamWaist)];
|
|
||||||
|
|
||||||
TotalAcceleration = zeros(1,3);
|
|
||||||
|
|
||||||
Delta_Cooling = [0,0,0,0];
|
|
||||||
Delta_Sideband = [0,0,0,0];
|
|
||||||
|
|
||||||
for i = 1:2
|
|
||||||
|
|
||||||
LocalMagneticField = this.magneticFieldForMOT(PositionVector);
|
|
||||||
|
|
||||||
B = sign(dot(LocalMagneticField(1:3), WaveVectorEndPoint(i,:))) * LocalMagneticField(4);
|
|
||||||
|
|
||||||
ZeemanShift = this.LandegFactor * this.MagneticSubLevel * (Helper.PhysicsConstants.BohrMagneton / Helper.PhysicsConstants.PlanckConstantReduced) * B;
|
|
||||||
|
|
||||||
DopplerShift = dot(WaveVectorEndPoint(i,:), VelocityVector) * CoolingBeamWaveNumber;
|
|
||||||
|
|
||||||
Delta_Cooling(i*2-1) = CoolingBeamDetuning + DopplerShift + (ZeemanShift * Sigma(i));
|
|
||||||
Delta_Cooling(i*2) = CoolingBeamDetuning - DopplerShift - (ZeemanShift * Sigma(i));
|
|
||||||
|
|
||||||
if this.SidebandBeam
|
|
||||||
Delta_Sideband(i*2-1) = SidebandDetuning + DopplerShift + (ZeemanShift * Sigma(i));
|
|
||||||
Delta_Sideband(i*2) = SidebandDetuning - DopplerShift - (ZeemanShift * Sigma(i));
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
SaturationParameter = [0,0,0,0,0,0,0,0];
|
|
||||||
|
|
||||||
for i = 1:2
|
|
||||||
SaturationParameter(2*i-1) = CoolingBeamLocalSaturationIntensity(i) /(1 + 4 * (Delta_Cooling(2*i-1)/CoolingBeamLinewidth)^2);
|
|
||||||
SaturationParameter(2*i) = CoolingBeamLocalSaturationIntensity(i) /(1 + 4 * (Delta_Cooling(2*i) /CoolingBeamLinewidth)^2);
|
|
||||||
if this.SidebandBeam
|
|
||||||
SaturationParameter(2*i-1+4) = SidebandLocalSaturationIntensity(i) /(1 + 4 * (Delta_Sideband(2*i-1)/CoolingBeamLinewidth)^2);
|
|
||||||
SaturationParameter(2*i+4) = SidebandLocalSaturationIntensity(i) /(1 + 4 * (Delta_Sideband(2*i)/CoolingBeamLinewidth)^2);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
TotalSaturationParameter = sum(SaturationParameter);
|
|
||||||
|
|
||||||
for i = 1:2
|
|
||||||
|
|
||||||
a_sat = (Helper.PhysicsConstants.PlanckConstantReduced * CoolingBeamWaveNumber * WaveVectorEndPoint(i,1:3)/Helper.PhysicsConstants.Dy164Mass).*(CoolingBeamLinewidth * 0.5);
|
|
||||||
a_1 = a_sat .* (SaturationParameter(2*i-1)/(1 + TotalSaturationParameter));
|
|
||||||
a_2 = a_sat .* (SaturationParameter(2*i) /(1 + TotalSaturationParameter));
|
|
||||||
|
|
||||||
if this.SpontaneousEmission
|
|
||||||
a_scattering = this.accelerationDueToSpontaneousEmissionProcess(SaturationParameter(2*i-1), TotalSaturationParameter, CoolingBeamLinewidth, CoolingBeamWaveNumber) + ...
|
|
||||||
this.accelerationDueToSpontaneousEmissionProcess(SaturationParameter(2*i), TotalSaturationParameter, CoolingBeamLinewidth, CoolingBeamWaveNumber);
|
|
||||||
else
|
|
||||||
a_scattering = [0,0,0];
|
|
||||||
end
|
|
||||||
|
|
||||||
if this.SidebandBeam
|
|
||||||
a_1 = a_1 + a_sat .* (SaturationParameter(2*i-1+4)/(1 + TotalSaturationParameter));
|
|
||||||
a_2 = a_2 + a_sat .* (SaturationParameter(2*i+4) /(1 + TotalSaturationParameter));
|
|
||||||
|
|
||||||
if this.SpontaneousEmission
|
|
||||||
a_scattering = a_scattering + ...
|
|
||||||
this.accelerationDueToSpontaneousEmissionProcess(SaturationParameter(2*i-1+4), TotalSaturationParameter, CoolingBeamLinewidth, CoolingBeamWaveNumber) + ...
|
|
||||||
this.accelerationDueToSpontaneousEmissionProcess(SaturationParameter(2*i+4), TotalSaturationParameter, CoolingBeamLinewidth, CoolingBeamWaveNumber);
|
|
||||||
else
|
|
||||||
a_scattering = [0,0,0];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
TotalAcceleration = TotalAcceleration + (a_2 - a_1) + a_scattering;
|
|
||||||
end
|
|
||||||
|
|
||||||
if this.PushBeam
|
|
||||||
TotalAcceleration = TotalAcceleration + this.accelerationDueToPushBeam(PositionVector, VelocityVector);
|
|
||||||
end
|
|
||||||
|
|
||||||
ret = TotalAcceleration(1:3);
|
|
||||||
|
|
||||||
end
|
|
@ -1,9 +0,0 @@
|
|||||||
function ret = computeCollisionProbability(this, ovenObj, tau_2D)
|
|
||||||
collision = rand(1);
|
|
||||||
CollisionProbability = 1 - exp(-tau_2D/ovenObj.CollisionTime);
|
|
||||||
if this.BackgroundCollision && collision <= CollisionProbability
|
|
||||||
ret = true;
|
|
||||||
else
|
|
||||||
ret = false;
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,20 +0,0 @@
|
|||||||
function T = computeTimeSpentInInteractionRegion(this, r)
|
|
||||||
% INPUT:
|
|
||||||
% r : N x 3 array. N is the number of time steps
|
|
||||||
% OUTPUT
|
|
||||||
% T : gives the distribution of time spent in the interaction region
|
|
||||||
% USAGE:
|
|
||||||
% T = this.computeTimeSpentInInteractionRegion(r)
|
|
||||||
T = 0;
|
|
||||||
CoolingBeamObj = this.Beams{cellfun(@(x) strcmpi(x.Alias, 'Blue'), this.Beams)};
|
|
||||||
NumberOfTimeSteps = int64(this.SimulationTime/this.TimeStep);
|
|
||||||
for n = 1:(NumberOfTimeSteps - 1)
|
|
||||||
dr = Helper.calculateDistanceFromPointToLine(r(n+1, :), [0 0 0], [0 0 1]);
|
|
||||||
if dr < CoolingBeamObj.Radius
|
|
||||||
A = 1;
|
|
||||||
else
|
|
||||||
A = 0;
|
|
||||||
end
|
|
||||||
T = T + A * this.TimeStep;
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,10 +0,0 @@
|
|||||||
function ret = exitCondition(this, PositionVector, CollisionEvent)
|
|
||||||
d = Helper.calculateDistanceFromPointToLine(PositionVector, [0 0 0], [0 1 0]);
|
|
||||||
y = PositionVector(2);
|
|
||||||
DivergenceAngle = atan(d/abs(y));
|
|
||||||
if (y >= 0) && (DivergenceAngle <= this.ExitDivergence) && ~CollisionEvent
|
|
||||||
ret = true;
|
|
||||||
else
|
|
||||||
ret = false;
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,50 +0,0 @@
|
|||||||
function [LoadingRate, StandardError, ConfidenceInterval] = jackknifeErrorEstimation(this, ovenObj, NumberOfLoadedAtoms)
|
|
||||||
n = this.NumberOfAtoms;
|
|
||||||
Autocorrelation = zeros(1, n);
|
|
||||||
|
|
||||||
for i = 1:n-1
|
|
||||||
FirstTerm = 0;
|
|
||||||
SecondTerm = 0;
|
|
||||||
for j = 1:n-i
|
|
||||||
FirstTerm = FirstTerm + NumberOfLoadedAtoms(j) / j;
|
|
||||||
SecondTerm = SecondTerm + (NumberOfLoadedAtoms(i+j)) / (i+j);
|
|
||||||
Autocorrelation(i) = Autocorrelation(i) + ((NumberOfLoadedAtoms(j) / j) .*(NumberOfLoadedAtoms(i+j) / (i+j)));
|
|
||||||
end
|
|
||||||
Autocorrelation(i) = (1/(n-i)) * (Autocorrelation(i) - ((1/(n-i)) * FirstTerm * SecondTerm));
|
|
||||||
end
|
|
||||||
|
|
||||||
if Autocorrelation(1)~=0
|
|
||||||
|
|
||||||
Autocorrelation = Autocorrelation./Autocorrelation(1);
|
|
||||||
|
|
||||||
x = linspace(1,n,n);
|
|
||||||
|
|
||||||
[FitParams,~] = fit(x',Autocorrelation',"exp(-x/tau)", 'Startpoint', 100);
|
|
||||||
CorrelationFactor = FitParams.tau;
|
|
||||||
|
|
||||||
SampleLength = 2*CorrelationFactor+1;
|
|
||||||
NumberOfJackknifeSamples = floor(n/SampleLength);
|
|
||||||
CaptureRatioInEachSample = zeros(1,NumberOfJackknifeSamples);
|
|
||||||
SampleNumberLimit = min(NumberOfJackknifeSamples-1,5);
|
|
||||||
for i=1:NumberOfJackknifeSamples-SampleNumberLimit
|
|
||||||
CaptureRatioInEachSample(i) = NumberOfLoadedAtoms(n-ceil((i-1)*SampleLength))/(n-ceil((i-1)*SampleLength));
|
|
||||||
end
|
|
||||||
|
|
||||||
MeanCaptureRatio = sum(CaptureRatioInEachSample) / (NumberOfJackknifeSamples-SampleNumberLimit);
|
|
||||||
|
|
||||||
LoadingRate = MeanCaptureRatio * ovenObj.ReducedFlux;
|
|
||||||
|
|
||||||
Variance=0;
|
|
||||||
for i=1:NumberOfJackknifeSamples-SampleNumberLimit
|
|
||||||
Variance=Variance+(CaptureRatioInEachSample(i) - MeanCaptureRatio)^2;
|
|
||||||
end
|
|
||||||
StandardError = sqrt(Variance/(NumberOfJackknifeSamples-SampleNumberLimit));
|
|
||||||
|
|
||||||
ConfidenceInterval = LoadingRate + 1.96*StandardError; % 95% Confidence Intervals
|
|
||||||
|
|
||||||
else
|
|
||||||
LoadingRate = nan;
|
|
||||||
StandardError = nan;
|
|
||||||
ConfidenceInterval = [nan nan];
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,8 +0,0 @@
|
|||||||
function ret = magneticFieldForMOT(this, r)
|
|
||||||
ret = zeros(1,4);
|
|
||||||
alpha = this.MagneticGradient;
|
|
||||||
ret(1) = r(3)*alpha;
|
|
||||||
ret(2) = 0;
|
|
||||||
ret(3) = r(1)*alpha;
|
|
||||||
ret(4) = sqrt(ret(1)^2+ret(2)^2+ret(3)^2);
|
|
||||||
end
|
|
@ -1,25 +0,0 @@
|
|||||||
function [LoadingRate, StandardError, ConfidenceInterval] = runSimulation(this, ovenObj)
|
|
||||||
if this.NumberOfAtoms ~= ovenObj.NumberOfAtoms
|
|
||||||
ovenObj.NumberOfAtoms = this.NumberOfAtoms;
|
|
||||||
end
|
|
||||||
%% - Sampling for initial positions and velocities
|
|
||||||
% - sampling the position distribution
|
|
||||||
Positions = ovenObj.initialPositionSampling();
|
|
||||||
% - sampling the velocity distribution
|
|
||||||
Velocities = ovenObj.initialVelocitySampling(this);
|
|
||||||
%% Solve ODE
|
|
||||||
progressbar = Helper.parforNotifications();
|
|
||||||
progressbar.PB_start(this.NumberOfAtoms,'Message',['Simulating 2-D MOT capture process for ' num2str(this.NumberOfAtoms,'%.0f') ' atoms:']);
|
|
||||||
|
|
||||||
% calculate the final position of the atoms
|
|
||||||
DynamicalQuantities = zeros(this.NumberOfAtoms,int64(this.SimulationTime/this.TimeStep),6);
|
|
||||||
parfor Index = 1:this.NumberOfAtoms
|
|
||||||
DynamicalQuantities(Index,:, :) = this.solver(Positions(Index,:), Velocities(Index,:));
|
|
||||||
progressbar.PB_iterate();
|
|
||||||
end
|
|
||||||
clear Index
|
|
||||||
this.ParticleDynamicalQuantities = DynamicalQuantities;
|
|
||||||
|
|
||||||
%% Calculate the Loading Rate
|
|
||||||
[LoadingRate, StandardError, ConfidenceInterval] = this.calculateLoadingRate(ovenObj);
|
|
||||||
end
|
|
@ -1,39 +0,0 @@
|
|||||||
function ParticleDynamicalQuantities = solver(this, InitialPosition, InitialVelocity)
|
|
||||||
if this.Gravity
|
|
||||||
g = [0,0,-Helper.PhysicsConstants.GravitationalAcceleration];
|
|
||||||
else
|
|
||||||
g = 0;
|
|
||||||
end
|
|
||||||
|
|
||||||
ParticleDynamicalQuantities = zeros(int64(this.SimulationTime/this.TimeStep),6);
|
|
||||||
for i=1:int64(this.SimulationTime/this.TimeStep)
|
|
||||||
|
|
||||||
ParticleDynamicalQuantities(i,1:3) = InitialPosition;
|
|
||||||
ParticleDynamicalQuantities(i,4:6) = InitialVelocity;
|
|
||||||
|
|
||||||
rt = InitialPosition;
|
|
||||||
vt = InitialVelocity;
|
|
||||||
|
|
||||||
ga1 = this.calculateTotalAcceleration(rt,vt) + g;
|
|
||||||
gv1 = vt .* this.TimeStep;
|
|
||||||
rt = rt + 0.5 * gv1;
|
|
||||||
vt = vt + 0.5 * ga1 .* this.TimeStep;
|
|
||||||
|
|
||||||
ga2 = this.calculateTotalAcceleration(rt,vt) + g;
|
|
||||||
gv2 = vt .* this.TimeStep;
|
|
||||||
rt = rt + 0.5 * gv2;
|
|
||||||
vt = vt + 0.5 * ga2 .* this.TimeStep;
|
|
||||||
|
|
||||||
ga3 = this.calculateTotalAcceleration(rt,vt) + g;
|
|
||||||
gv3 = vt .* this.TimeStep;
|
|
||||||
rt = rt + 0.5 * gv3;
|
|
||||||
vt = vt + ga3 .* this.TimeStep;
|
|
||||||
|
|
||||||
ga4 = this.calculateTotalAcceleration(rt,vt) + g;
|
|
||||||
gv4 = vt .* this.TimeStep;
|
|
||||||
|
|
||||||
InitialPosition = InitialPosition + (gv1+2*(gv2+gv3)+gv4)./6;
|
|
||||||
InitialVelocity = InitialVelocity + this.TimeStep*(ga1+2*(ga2+ga3)+ga4)./6;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,427 +0,0 @@
|
|||||||
%% This script is testing the functionalities of the MOT Capture Process Simulation Classes
|
|
||||||
%
|
|
||||||
% Important: Run only sectionwise!!
|
|
||||||
|
|
||||||
%% - Testing the MOTCaptureProcess-Class
|
|
||||||
% - Create MOTCaptureProcess object with specified options
|
|
||||||
% - Automatically creates Beams objects
|
|
||||||
OptionsStruct = struct;
|
|
||||||
OptionsStruct.ErrorEstimationMethod = 'bootstrap'; % 'jackknife' | 'bootstrap'
|
|
||||||
OptionsStruct.NumberOfAtoms = 5000;
|
|
||||||
OptionsStruct.TimeStep = 50e-06; % in s
|
|
||||||
OptionsStruct.SimulationTime = 4e-03; % in s
|
|
||||||
OptionsStruct.SpontaneousEmission = true;
|
|
||||||
OptionsStruct.SidebandBeam = true;
|
|
||||||
OptionsStruct.PushBeam = true;
|
|
||||||
OptionsStruct.Gravity = true;
|
|
||||||
OptionsStruct.BackgroundCollision = true;
|
|
||||||
OptionsStruct.SaveData = true;
|
|
||||||
% OptionsStruct.SaveDirectory = '';
|
|
||||||
options = Helper.convertstruct2cell(OptionsStruct);
|
|
||||||
clear OptionsStruct
|
|
||||||
|
|
||||||
Oven = Simulator.Oven(options{:});
|
|
||||||
MOT2D = Simulator.TwoDimensionalMOT(options{:});
|
|
||||||
Beams = MOT2D.Beams;
|
|
||||||
|
|
||||||
%% - Run Simulation
|
|
||||||
MOT2D.NumberOfAtoms = 10000;
|
|
||||||
MOT2D.SidebandBeam = true;
|
|
||||||
MOT2D.PushBeam = false;
|
|
||||||
CoolingBeam = Beams{cellfun(@(x) strcmpi(x.Alias, 'Blue'), Beams)};
|
|
||||||
CoolingBeam.Power = 0.2;
|
|
||||||
CoolingBeam.Waist = 20e-03;
|
|
||||||
CoolingBeam.Detuning = -1.33*Helper.PhysicsConstants.BlueLinewidth;
|
|
||||||
SidebandBeam = Beams{cellfun(@(x) strcmpi(x.Alias, 'BlueSideband'), Beams)};
|
|
||||||
SidebandBeam.Power = 0.2;
|
|
||||||
SidebandBeam.Waist = 20e-03;
|
|
||||||
SidebandBeam.Detuning = -2.66*Helper.PhysicsConstants.BlueLinewidth;
|
|
||||||
PushBeam = Beams{cellfun(@(x) strcmpi(x.Alias, 'Push'), Beams)};
|
|
||||||
PushBeam.Power = 0.025;
|
|
||||||
PushBeam.Waist = 0.81e-03;
|
|
||||||
PushBeam.Detuning = 0;
|
|
||||||
[LoadingRate, ~] = MOT2D.runSimulation(Oven);
|
|
||||||
%% - Plot initial distribution
|
|
||||||
% - sampling the position distribution
|
|
||||||
InitialPositions = Oven.initialPositionSampling();
|
|
||||||
% - sampling the velocity distribution
|
|
||||||
InitialVelocities = Oven.initialVelocitySampling(MOT2D);
|
|
||||||
NumberOfBins = 100;
|
|
||||||
Plotter.plotPositionAndVelocitySampling(NumberOfBins, InitialPositions, InitialVelocities);
|
|
||||||
|
|
||||||
%% - Plot distributions of magnitude and direction of initial velocities
|
|
||||||
NumberOfBins = 50;
|
|
||||||
Plotter.plotInitialVeloctiySamplingVsAngle(Oven, MOT2D, NumberOfBins)
|
|
||||||
|
|
||||||
%% - Plot Magnetic Field
|
|
||||||
XAxisRange = [-5 5];
|
|
||||||
YAxisRange = [-5 5];
|
|
||||||
ZAxisRange = [-5 5];
|
|
||||||
Plotter.visualizeMagneticField(MOT2D, XAxisRange, YAxisRange, ZAxisRange)
|
|
||||||
|
|
||||||
%% - Plot MFP & VP for different temperatures
|
|
||||||
TemperatureinCelsius = linspace(750,1100,2000); % Temperature in Celsius
|
|
||||||
Plotter.plotMeanFreePathAndVapourPressureVsTemp(TemperatureinCelsius)
|
|
||||||
|
|
||||||
%% - Plot the Free Molecular Flux for different temperatures
|
|
||||||
Temperature = [950, 1000, 1050]; % Temperature
|
|
||||||
Plotter.plotFreeMolecularFluxVsTemp(Oven,Temperature)
|
|
||||||
|
|
||||||
%% - Plot Angular Distribution for different Beta
|
|
||||||
Beta = [0.5, 0.1 , 0.05, 0.02, 0.01]; %Beta = 2 * radius / length of the tube
|
|
||||||
Plotter.plotAngularDistributionForDifferentBeta(Oven, Beta)
|
|
||||||
|
|
||||||
%% - Plot Capture Velocity
|
|
||||||
Plotter.plotCaptureVelocityVsAngle(Oven, MOT2D); % Takes a long time to plot!
|
|
||||||
|
|
||||||
%% - Plot Phase Space with Acceleration Field
|
|
||||||
MOT2D.SidebandBeam = false;
|
|
||||||
MOT2D.MagneticGradient = 0.4;
|
|
||||||
CoolingBeam = Beams{cellfun(@(x) strcmpi(x.Alias, 'Blue'), Beams)};
|
|
||||||
CoolingBeam.Power = 0.3;
|
|
||||||
CoolingBeam.Detuning = -1.64*Helper.PhysicsConstants.BlueLinewidth;
|
|
||||||
CoolingBeam.Waist = 15e-03;
|
|
||||||
SidebandBeam = Beams{cellfun(@(x) strcmpi(x.Alias, 'BlueSideband'), Beams)};
|
|
||||||
SidebandBeam.Power = 0.5;
|
|
||||||
SidebandBeam.Detuning = -4*Helper.PhysicsConstants.BlueLinewidth;
|
|
||||||
SidebandBeam.Waist = 15e-03;
|
|
||||||
MOT2D.NumberOfAtoms = 50;
|
|
||||||
MinimumVelocity = 0;
|
|
||||||
MaximumVelocity = 150;
|
|
||||||
NumberOfBins = 200; %Along each axis
|
|
||||||
IncidentAtomDirection = 0*2*pi/360;
|
|
||||||
IncidentAtomPosition = 0;
|
|
||||||
Plotter.plotPhaseSpaceWithAccelerationField(Oven, MOT2D, MinimumVelocity, MaximumVelocity, NumberOfBins, IncidentAtomDirection, IncidentAtomPosition)
|
|
||||||
|
|
||||||
%% - Plot Trajectories along the 3 directions
|
|
||||||
MOT2D.NumberOfAtoms = 100;
|
|
||||||
MOT2D.MagneticGradient = 0.42;
|
|
||||||
MaximumVelocity = 150;
|
|
||||||
IncidentAtomDirection = 0*2*pi/360;
|
|
||||||
IncidentAtomPosition = 0;
|
|
||||||
|
|
||||||
%% - Positions
|
|
||||||
Plotter.plotDynamicalQuantities(Oven, MOT2D, MaximumVelocity, IncidentAtomDirection, IncidentAtomPosition, 'PlotPositions', true);
|
|
||||||
|
|
||||||
%% - Velocities
|
|
||||||
Plotter.plotDynamicalQuantities(Oven, MOT2D, MaximumVelocity, IncidentAtomDirection, IncidentAtomPosition, 'PlotVelocities', true);
|
|
||||||
|
|
||||||
%% - Scan parameters: One-Parameter Scan
|
|
||||||
|
|
||||||
MOT2D.NumberOfAtoms = 5000;
|
|
||||||
MOT2D.TotalPower = 0.4;
|
|
||||||
MOT2D.SidebandBeam = false;
|
|
||||||
MOT2D.PushBeam = false;
|
|
||||||
NumberOfPointsForFirstParam = 5; %iterations of the simulation
|
|
||||||
ParameterArray = linspace(0.1, 1.0, NumberOfPointsForFirstParam) * MOT2D.TotalPower;
|
|
||||||
|
|
||||||
tStart = tic;
|
|
||||||
[LoadingRateArray, StandardErrorArray, ConfidenceIntervalArray] = Simulator.Scan.doOneParameter(Oven, MOT2D, 'Blue', 'Power', ParameterArray);
|
|
||||||
tEnd = toc(tStart);
|
|
||||||
fprintf('Total Computational Time: %0.1f seconds. \n', tEnd);
|
|
||||||
|
|
||||||
% - Plot results
|
|
||||||
|
|
||||||
OptionsStruct = struct;
|
|
||||||
OptionsStruct.RescalingFactorForParameter = 1000;
|
|
||||||
OptionsStruct.XLabelString = 'Cooling Beam Power (mW)';
|
|
||||||
OptionsStruct.RescalingFactorForYQuantity = 1e-10;
|
|
||||||
OptionsStruct.ErrorsForYQuantity = true;
|
|
||||||
OptionsStruct.ErrorsArray = StandardErrorArray;
|
|
||||||
OptionsStruct.CIForYQuantity = true;
|
|
||||||
OptionsStruct.CIArray = ConfidenceIntervalArray;
|
|
||||||
OptionsStruct.RemoveOutliers = true;
|
|
||||||
OptionsStruct.YLabelString = 'Loading rate (x 10^{10} atoms/s)';
|
|
||||||
OptionsStruct.TitleString = sprintf('Magnetic Gradient = %.0f (G/cm)', MOT2D.MagneticGradient * 100);
|
|
||||||
|
|
||||||
options = Helper.convertstruct2cell(OptionsStruct);
|
|
||||||
|
|
||||||
Plotter.plotResultForOneParameterScan(ParameterArray, LoadingRateArray, options{:})
|
|
||||||
|
|
||||||
clear OptionsStruct
|
|
||||||
|
|
||||||
%% - Scan parameters: One-Parameter Scan
|
|
||||||
MOT2D.NumberOfAtoms = 10000;
|
|
||||||
CoolingBeam = Beams{cellfun(@(x) strcmpi(x.Alias, 'Blue'), Beams)};
|
|
||||||
CoolingBeam.Power = 0.4;
|
|
||||||
MOT2D.SidebandBeam = false;
|
|
||||||
MOT2D.PushBeam = false;
|
|
||||||
% ParameterArray = [10 20 30 40 50 60 70 80 90 100];
|
|
||||||
ParameterArray = [500 1000 1500 2000 2500 3000 3500 4000 4500 5000 5500 6000 6500 7000 7500 8000 8500 9000 9500];
|
|
||||||
NumberOfPointsForParam = length(ParameterArray); %iterations of the simulation
|
|
||||||
|
|
||||||
LoadingRateArray = zeros(1,NumberOfPointsForParam);
|
|
||||||
StandardErrorArray = zeros(1,NumberOfPointsForParam);
|
|
||||||
ConfidenceIntervalArray = zeros(NumberOfPointsForParam, 2);
|
|
||||||
tStart = tic;
|
|
||||||
for i=1:NumberOfPointsForParam
|
|
||||||
MOT2D.BootstrapSampleLength = ParameterArray(i);
|
|
||||||
[LoadingRateArray(i), StandardErrorArray(i), ConfidenceIntervalArray(i,:)] = MOT2D.runSimulation(Oven);
|
|
||||||
end
|
|
||||||
tEnd = toc(tStart);
|
|
||||||
fprintf('Total Computational Time: %0.1f seconds. \n', tEnd);
|
|
||||||
|
|
||||||
|
|
||||||
% - Plot results
|
|
||||||
|
|
||||||
OptionsStruct = struct;
|
|
||||||
OptionsStruct.RescalingFactorForParameter = 1;
|
|
||||||
OptionsStruct.XLabelString = 'Bootstrap Sample Length';
|
|
||||||
OptionsStruct.RescalingFactorForYQuantity = 1e-10;
|
|
||||||
OptionsStruct.ErrorsForYQuantity = true;
|
|
||||||
OptionsStruct.ErrorsArray = StandardErrorArray;
|
|
||||||
OptionsStruct.CIForYQuantity = true;
|
|
||||||
OptionsStruct.CIArray = ConfidenceIntervalArray;
|
|
||||||
OptionsStruct.RemoveOutliers = false;
|
|
||||||
OptionsStruct.YLabelString = 'Loading rate (x 10^{10} atoms/s)';
|
|
||||||
OptionsStruct.TitleString = sprintf('Cooling Beam Power = %d (mW); Magnetic Gradient = %.0f (G/cm)', CoolingBeam.Power*1000, MOT2D.MagneticGradient * 100);
|
|
||||||
|
|
||||||
options = Helper.convertstruct2cell(OptionsStruct);
|
|
||||||
|
|
||||||
Plotter.plotResultForOneParameterScan(ParameterArray, LoadingRateArray, options{:})
|
|
||||||
|
|
||||||
MeanLR = mean(LoadingRateArray(:)) * 1e-10;
|
|
||||||
|
|
||||||
yline(MeanLR, 'LineStyle', '--', 'Linewidth', 2.5)
|
|
||||||
textstring = [sprintf('%1.2e', MeanLR * 1e+10) ' atoms'];
|
|
||||||
% txt = text((ParameterArray(2) + 0.05*ParameterArray(2)), (max(MeanLR) + 0.05*MeanLR), textstring, 'Interpreter','latex', 'FontSize', 14);
|
|
||||||
|
|
||||||
% xlim([0 100])
|
|
||||||
ylim([0 3.5])
|
|
||||||
|
|
||||||
clear OptionsStruct
|
|
||||||
%% - Scan parameters: Two-Parameter Scan
|
|
||||||
|
|
||||||
% COOLING BEAM POWER VS DETUNING
|
|
||||||
|
|
||||||
MOT2D.NumberOfAtoms = 5000;
|
|
||||||
MOT2D.TotalPower = 0.6;
|
|
||||||
NumberOfPointsForFirstParam = 10; %iterations of the simulation
|
|
||||||
NumberOfPointsForSecondParam = 10;
|
|
||||||
FirstParameterArray = linspace(-0.5, -2.5, NumberOfPointsForFirstParam) * Helper.PhysicsConstants.BlueLinewidth;
|
|
||||||
SecondParameterArray = linspace(0.3, 1.0, NumberOfPointsForSecondParam) * MOT2D.TotalPower;
|
|
||||||
|
|
||||||
tStart = tic;
|
|
||||||
[LoadingRateArray, ~, ~] = Simulator.Scan.doTwoParameters(Oven, MOT2D, 'Blue', 'Detuning', FirstParameterArray, 'Power', SecondParameterArray);
|
|
||||||
tEnd = toc(tStart);
|
|
||||||
fprintf('Total Computational Time: %0.1f seconds. \n', tEnd);
|
|
||||||
|
|
||||||
% - Plot results
|
|
||||||
|
|
||||||
OptionsStruct = struct;
|
|
||||||
OptionsStruct.RescalingFactorForFirstParameter = (Helper.PhysicsConstants.BlueLinewidth)^-1;
|
|
||||||
OptionsStruct.XLabelString = 'Cooling Beam Detuning (\Delta/\Gamma)';
|
|
||||||
OptionsStruct.RescalingFactorForSecondParameter = 1000;
|
|
||||||
OptionsStruct.YLabelString = 'Cooling Beam Power (mW)';
|
|
||||||
OptionsStruct.RescalingFactorForQuantityOfInterest = 1e-9;
|
|
||||||
OptionsStruct.ZLabelString = 'Loading rate (x 10^{9} atoms/s)';
|
|
||||||
OptionsStruct.TitleString = sprintf('Magnetic Gradient = %.0f (G/cm)', MOT2D.MagneticGradient * 100);
|
|
||||||
|
|
||||||
options = Helper.convertstruct2cell(OptionsStruct);
|
|
||||||
|
|
||||||
Plotter.plotResultForTwoParameterScan(FirstParameterArray, SecondParameterArray, LoadingRateArray, options{:})
|
|
||||||
|
|
||||||
clear OptionsStruct
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
%% COOLING BEAM WAIST VS DETUNING
|
|
||||||
|
|
||||||
MOT2D.NumberOfAtoms = 20000;
|
|
||||||
MOT2D.MagneticGradient = 0.40;
|
|
||||||
MOT2D.SidebandBeam = false;
|
|
||||||
MOT2D.PushBeam = false;
|
|
||||||
CoolingBeam = Beams{cellfun(@(x) strcmpi(x.Alias, 'Blue'), Beams)};
|
|
||||||
CoolingBeam.Power = 0.4;
|
|
||||||
NumberOfPointsForFirstParam = 10; %iterations of the simulation
|
|
||||||
NumberOfPointsForSecondParam = 10;
|
|
||||||
FirstParameterArray = linspace(-0.5, -2.0, NumberOfPointsForFirstParam) * Helper.PhysicsConstants.BlueLinewidth;
|
|
||||||
SecondParameterArray = linspace(10, 25, NumberOfPointsForSecondParam) * 1e-03;
|
|
||||||
|
|
||||||
tStart = tic;
|
|
||||||
[LoadingRateArray, ~, ~] = Simulator.Scan.doTwoParameters(Oven, MOT2D, 'Blue', 'Detuning', FirstParameterArray, 'Waist', SecondParameterArray);
|
|
||||||
tEnd = toc(tStart);
|
|
||||||
fprintf('Total Computational Time: %0.1f seconds. \n', tEnd);
|
|
||||||
|
|
||||||
% - Plot results
|
|
||||||
|
|
||||||
OptionsStruct = struct;
|
|
||||||
OptionsStruct.RescalingFactorForFirstParameter = (Helper.PhysicsConstants.BlueLinewidth)^-1;
|
|
||||||
OptionsStruct.XLabelString = 'Cooling Beam Detuning (\Delta/\Gamma)';
|
|
||||||
OptionsStruct.RescalingFactorForSecondParameter = 1000;
|
|
||||||
OptionsStruct.YLabelString = 'Cooling Beam Waist (mm)';
|
|
||||||
OptionsStruct.RescalingFactorForQuantityOfInterest = 1e-9;
|
|
||||||
OptionsStruct.ZLabelString = 'Loading rate (x 10^{9} atoms/s)';
|
|
||||||
OptionsStruct.TitleString = sprintf('Cooling Beam Power = %d (mW); Magnetic Gradient = %.0f (G/cm)', CoolingBeam.Power*1000, MOT2D.MagneticGradient * 100);
|
|
||||||
|
|
||||||
options = Helper.convertstruct2cell(OptionsStruct);
|
|
||||||
|
|
||||||
Plotter.plotResultForTwoParameterScan(FirstParameterArray, SecondParameterArray, LoadingRateArray, options{:})
|
|
||||||
|
|
||||||
clear OptionsStruct
|
|
||||||
|
|
||||||
%% - Scan parameters: Three-Parameter Scan
|
|
||||||
|
|
||||||
% COOLING BEAM WAIST VS DETUNING FOR DIFFERENT MAGNETIC FIELD GRADIENTS
|
|
||||||
|
|
||||||
MOT2D.NumberOfAtoms = 10000;
|
|
||||||
MOT2D.SidebandBeam = false;
|
|
||||||
MOT2D.PushBeam = false;
|
|
||||||
MOT2D.BackgroundCollision = false;
|
|
||||||
CoolingBeam = Beams{cellfun(@(x) strcmpi(x.Alias, 'Blue'), Beams)};
|
|
||||||
CoolingBeam.Power = 0.4;
|
|
||||||
NumberOfPointsForFirstParam = 10; %iterations of the simulation
|
|
||||||
NumberOfPointsForSecondParam = 10;
|
|
||||||
NumberOfPointsForThirdParam = 6;
|
|
||||||
FirstParameterArray = linspace(-0.5, -2.0, NumberOfPointsForFirstParam) * Helper.PhysicsConstants.BlueLinewidth;
|
|
||||||
SecondParameterArray = linspace(10, 25, NumberOfPointsForSecondParam) * 1e-03;
|
|
||||||
ThirdParameterArray = linspace(30, 50, NumberOfPointsForThirdParam) * 1e-02;
|
|
||||||
MOT2D.BootstrapSampleLength = 500;
|
|
||||||
|
|
||||||
tStart = tic;
|
|
||||||
LoadingRateArray = Simulator.Scan.doThreeParameters(Oven, MOT2D, 'Blue', 'Detuning', FirstParameterArray, ...
|
|
||||||
'Waist', SecondParameterArray, ...
|
|
||||||
'MagneticGradient', ThirdParameterArray);
|
|
||||||
tEnd = toc(tStart);
|
|
||||||
fprintf('Total Computational Time: %0.1f seconds. \n', tEnd);
|
|
||||||
|
|
||||||
% - Plot results
|
|
||||||
|
|
||||||
OptionsStruct = struct;
|
|
||||||
OptionsStruct.RescalingFactorForFirstParameter = (Helper.PhysicsConstants.BlueLinewidth)^-1;
|
|
||||||
OptionsStruct.XLabelString = 'Cooling Beam Detuning (\Delta/\Gamma)';
|
|
||||||
OptionsStruct.RescalingFactorForSecondParameter = 1000;
|
|
||||||
OptionsStruct.YLabelString = 'Cooling Beam Waist (mm)';
|
|
||||||
OptionsStruct.RescalingFactorForThirdParameter = 100;
|
|
||||||
OptionsStruct.RescalingFactorForQuantityOfInterest = 1e-9;
|
|
||||||
OptionsStruct.ZLabelString = 'Loading rate (x 10^{9} atoms/s)';
|
|
||||||
OptionsStruct.PlotTitleString = 'Magnetic Gradient = %.0f (G/cm)';
|
|
||||||
OptionsStruct.FigureTitleString = sprintf('Oven-2DMOT Distance = %.1f (mm); Cooling Beam Power = %d (mW)', Oven.OvenDistance * 1000, CoolingBeam.Power*1000);
|
|
||||||
|
|
||||||
options = Helper.convertstruct2cell(OptionsStruct);
|
|
||||||
|
|
||||||
Plotter.plotResultForThreeParameterScan(FirstParameterArray, SecondParameterArray, ThirdParameterArray, LoadingRateArray, options{:})
|
|
||||||
|
|
||||||
clear OptionsStruct
|
|
||||||
|
|
||||||
%% Local Saturation Intensity distribution
|
|
||||||
|
|
||||||
WaveVectorEndPoint = zeros(2,3);
|
|
||||||
WaveVectorEndPoint(1,:) = [1,0,1];
|
|
||||||
WaveVectorEndPoint(1,:) = WaveVectorEndPoint(1,1:3)/norm(WaveVectorEndPoint(1,:));
|
|
||||||
WaveVectorEndPoint(2,:) = [-1,0,1];
|
|
||||||
WaveVectorEndPoint(2,:) = WaveVectorEndPoint(2,1:3)/norm(WaveVectorEndPoint(2,:));
|
|
||||||
Origin = [0,0,0];
|
|
||||||
|
|
||||||
BeamNumber = 2; %Selects one of the two wave vectors defined above
|
|
||||||
BeamRadius = 17.5e-03;
|
|
||||||
BeamWaist = 15e-03;
|
|
||||||
Power = 0.4;
|
|
||||||
CoolingBeam = Beams{cellfun(@(x) strcmpi(x.Alias, 'Blue'), Beams)};
|
|
||||||
SaturationIntensity = CoolingBeam.SaturationIntensity;
|
|
||||||
SaturationParameter = 0.1 * (8 * Power) / (pi*BeamWaist^2 * SaturationIntensity); % two beams are reflected
|
|
||||||
|
|
||||||
n = 10000;
|
|
||||||
xmin = -BeamRadius;
|
|
||||||
xmax = BeamRadius;
|
|
||||||
x = xmin+rand(n,1)*(xmax-xmin);
|
|
||||||
|
|
||||||
y = ones(n,1) * 0;
|
|
||||||
|
|
||||||
zmin = -BeamRadius;
|
|
||||||
zmax = BeamRadius;
|
|
||||||
z = zmin+rand(n,1)*(zmax-zmin);
|
|
||||||
|
|
||||||
|
|
||||||
% t = 2*pi*rand(n,1);
|
|
||||||
% r = BeamRadius*sqrt(rand(n,1));
|
|
||||||
% x = r.*cos(t);
|
|
||||||
% y = ones(n,1) * 0;
|
|
||||||
% z = r.*sin(t);
|
|
||||||
|
|
||||||
PositionVector = horzcat(x, y, z); %scatter3(zeros(n,1), y, z)
|
|
||||||
CoolingBeamLocalSaturationIntensity = @(x) MOT2D.calculateLocalSaturationIntensity(0.25 * SaturationParameter, x, Origin, WaveVectorEndPoint(BeamNumber,:), BeamRadius, BeamWaist);
|
|
||||||
IntensityProfile = zeros(n,1);
|
|
||||||
for i=1:n
|
|
||||||
IntensityProfile(i) = CoolingBeamLocalSaturationIntensity(PositionVector(i, :));
|
|
||||||
end
|
|
||||||
|
|
||||||
v = IntensityProfile; % Extract intensity value
|
|
||||||
rows = 35;
|
|
||||||
columns = 35;
|
|
||||||
Image = zeros(rows, columns);
|
|
||||||
for k = 1 : length(x)
|
|
||||||
row = ceil((x(k) - min(x)) * columns / (max(x) - min(x)));
|
|
||||||
column = ceil((z(k) - min(z)) * rows / (max(z) - min(z)));
|
|
||||||
if (row == 0)
|
|
||||||
row = 1;
|
|
||||||
end
|
|
||||||
if (column == 0)
|
|
||||||
column = 1;
|
|
||||||
end
|
|
||||||
Image(row, column) = v(k);
|
|
||||||
end
|
|
||||||
|
|
||||||
f_h = Helper.getFigureByTag('Intensity Profile');
|
|
||||||
set(groot,'CurrentFigure',f_h);
|
|
||||||
a_h = get(f_h, 'CurrentAxes');
|
|
||||||
if ~isempty(get(a_h, 'Children'))
|
|
||||||
clf(f_h);
|
|
||||||
end
|
|
||||||
f_h.Name = 'Intensity Profile';
|
|
||||||
f_h.Units = 'pixels';
|
|
||||||
set(0,'units','pixels');
|
|
||||||
screensize = get(0,'ScreenSize');
|
|
||||||
f_h.Position = [[screensize(3)/3.5 screensize(4)/3.5] 750 600];
|
|
||||||
imagesc(linspace(min(x),max(x),row) * 1e+03, linspace(min(z),max(z),column) * 1e+03, Image);
|
|
||||||
set(gca,'YDir','normal');
|
|
||||||
hXLabel = xlabel('x-direction (distance in mm)');
|
|
||||||
hYLabel = ylabel('z-direction (distance in mm)');
|
|
||||||
|
|
||||||
shading flat;
|
|
||||||
c = colorbar;
|
|
||||||
c.Label.String= 'Local Saturation Intensity';
|
|
||||||
c.Label.FontSize = 14;
|
|
||||||
|
|
||||||
hTitle = sgtitle('Intensity Distribution');
|
|
||||||
|
|
||||||
set([hXLabel, hYLabel] , ...
|
|
||||||
'FontSize' , 14 );
|
|
||||||
set( hTitle , ...
|
|
||||||
'FontSize' , 18 );
|
|
||||||
|
|
||||||
Helper.bringFiguresWithTagInForeground();
|
|
||||||
|
|
||||||
%% Beam Shape in Three dimensions
|
|
||||||
|
|
||||||
f_h = Helper.getFigureByTag('Intensity Profile');
|
|
||||||
set(groot,'CurrentFigure',f_h);
|
|
||||||
a_h = get(f_h, 'CurrentAxes');
|
|
||||||
if ~isempty(get(a_h, 'Children'))
|
|
||||||
clf(f_h);
|
|
||||||
end
|
|
||||||
f_h.Name = 'Intensity Profile';
|
|
||||||
f_h.Units = 'pixels';
|
|
||||||
set(0,'units','pixels');
|
|
||||||
screensize = get(0,'ScreenSize');
|
|
||||||
f_h.Position = [[screensize(3)/3.5 screensize(4)/3.5] 750 600];
|
|
||||||
[xq,zq] = meshgrid(linspace(-BeamRadius, BeamRadius, n), linspace(-BeamRadius, BeamRadius, n));
|
|
||||||
vq = griddata(x,z,v,xq,zq);
|
|
||||||
mesh(xq,zq,vq)
|
|
||||||
hold on
|
|
||||||
plot3(x,z,v,'o', 'MarkerSize', 1.5)
|
|
||||||
hXLabel = xlabel('x-direction (distance in mm)');
|
|
||||||
hYLabel = ylabel('z-direction (distance in mm)');
|
|
||||||
shading flat;
|
|
||||||
c = colorbar;
|
|
||||||
c.Label.String= 'Local Saturation Intensity';
|
|
||||||
c.Label.FontSize = 14;
|
|
||||||
|
|
||||||
hTitle = sgtitle('Intensity Distribution');
|
|
||||||
|
|
||||||
set([hXLabel, hYLabel] , ...
|
|
||||||
'FontSize' , 14 );
|
|
||||||
set( hTitle , ...
|
|
||||||
'FontSize' , 18 );
|
|
||||||
|
|
||||||
Helper.bringFiguresWithTagInForeground();
|
|
||||||
|
|
@ -1,510 +0,0 @@
|
|||||||
import numpy as np
|
|
||||||
from scipy.optimize import curve_fit
|
|
||||||
from scipy import interpolate
|
|
||||||
from astropy import units as u, constants as ac
|
|
||||||
|
|
||||||
from Potentials import *
|
|
||||||
from Helpers import *
|
|
||||||
|
|
||||||
DY_POLARIZABILITY = 184.4 # in a.u, most precise measured value of Dy polarizability
|
|
||||||
DY_MASS = 164*u.u
|
|
||||||
DY_DIPOLE_MOMENT = 9.93 * ac.muB
|
|
||||||
|
|
||||||
#####################################################################
|
|
||||||
# AUXILIARY COMPUTATIONS
|
|
||||||
#####################################################################
|
|
||||||
|
|
||||||
def calculateHeatingRate(w_x, w_y, P, linewidth, detuning, wavelength = 1.064*u.um):
|
|
||||||
U = trap_depth(w_x, w_y, P).decompose()
|
|
||||||
Gamma_sr = ((linewidth * U) / (ac.hbar * detuning)).decompose()
|
|
||||||
E_recoil = (ac.h**2 / (2 * DY_MASS * wavelength**2)).decompose()
|
|
||||||
T_recoil = (E_recoil/ac.k_B).to(u.uK)
|
|
||||||
HeatingRate = 2/3 * Gamma_sr * T_recoil
|
|
||||||
return HeatingRate, T_recoil, Gamma_sr, U
|
|
||||||
|
|
||||||
def calculateAtomNumber(NCount, pixel_size, magnification, eta):
|
|
||||||
sigma = 8.468e-14 * (u.m)**(2)
|
|
||||||
return (1/eta * 1/sigma * NCount * pixel_size**2/magnification**2).decompose()
|
|
||||||
|
|
||||||
def meanThermalVelocity(T, m = DY_MASS):
|
|
||||||
return 4 * np.sqrt((ac.k_B * T) /(np.pi * m))
|
|
||||||
|
|
||||||
def particleDensity(w_x, w_z, Power, N, T, m = DY_MASS): # For a thermal cloud
|
|
||||||
v_x = calculateTrapFrequency(w_x, w_z, Power, dir = 'x')
|
|
||||||
v_y = calculateTrapFrequency(w_x, w_z, Power, dir = 'y')
|
|
||||||
v_z = calculateTrapFrequency(w_x, w_z, Power, dir = 'z')
|
|
||||||
return N * (2 * np.pi)**3 * (v_x * v_y * v_z) * (m / (2 * np.pi * ac.k_B * T))**(3/2)
|
|
||||||
|
|
||||||
def calculateParticleDensityFromMeasurements(v_x, dv_x, v_y, dv_y, v_z, dv_z, w_x, w_z, T_x, T_y, dT_x, dT_y, modulation_depth, N, m = DY_MASS):
|
|
||||||
alpha_x = [(v_x[0]/x)**(2/3) for x in v_x]
|
|
||||||
dalpha_x = [alpha_x[i] * np.sqrt((dv_x[0]/v_x[0])**2 + (dv_x[i]/v_x[i])**2) for i in range(len(v_x))]
|
|
||||||
alpha_y = [(v_z[0]/y)**2 for y in v_z]
|
|
||||||
dalpha_y = [alpha_y[i] * np.sqrt((dv_z[0]/v_z[0])**2 + (dv_z[i]/v_z[i])**2) for i in range(len(v_z))]
|
|
||||||
|
|
||||||
avg_alpha = [(g + h) / 2 for g, h in zip(alpha_x, alpha_y)]
|
|
||||||
new_aspect_ratio = (w_x * avg_alpha) / w_z
|
|
||||||
|
|
||||||
avg_T = [(g + h) / 2 for g, h in zip(T_x, T_y)]
|
|
||||||
avg_dT = [0.5 * np.sqrt(g**2 + h**2) for g, h in zip(dT_x, dT_y)]
|
|
||||||
|
|
||||||
pd = np.zeros(len(modulation_depth))
|
|
||||||
dpd = np.zeros(len(modulation_depth))
|
|
||||||
|
|
||||||
for i in range(len(modulation_depth)):
|
|
||||||
particle_density = (N * (2 * np.pi)**3 * (v_x[i] * v_y[i] * v_z[i]) * (m / (2 * np.pi * ac.k_B * avg_T[i]))**(3/2)).decompose()
|
|
||||||
pd[i] = particle_density.value
|
|
||||||
dpd[i] = (((N * (2 * np.pi)**3 * (m / (2 * np.pi * ac.k_B * avg_T[i]))**(3/2)) * ((dv_x[i] * v_y[i] * v_z[i]) + (v_x[i] * dv_y[i] * v_z[i]) + (v_x[i] * v_y[i] * dv_z[i]) - (1.5*(v_x[i] * v_y[i] * v_z[i])*(avg_dT[i]/avg_T[i])))).decompose()).value
|
|
||||||
|
|
||||||
pd = pd*particle_density.unit
|
|
||||||
dpd = dpd*particle_density.unit
|
|
||||||
|
|
||||||
return pd, dpd, avg_T, avg_dT, new_aspect_ratio
|
|
||||||
|
|
||||||
def thermaldeBroglieWavelength(T, m = DY_MASS):
|
|
||||||
return np.sqrt((2*np.pi*ac.hbar**2)/(m*ac.k_B*T))
|
|
||||||
|
|
||||||
def scatteringLength(B, FR_choice = 1, ABKG_choice = 1):
|
|
||||||
# Dy 164 a_s versus B in 0 to 8G range
|
|
||||||
# should match SupMat of PhysRevX.9.021012, fig S5 and descrption
|
|
||||||
# https://journals.aps.org/prx/supplemental/10.1103/PhysRevX.9.021012/Resubmission_Suppmat.pdf
|
|
||||||
|
|
||||||
if FR_choice == 1: # new values
|
|
||||||
|
|
||||||
if ABKG_choice == 1:
|
|
||||||
a_bkg = 85.5 * ac.a0
|
|
||||||
elif ABKG_choice == 2:
|
|
||||||
a_bkg = 93.5 * ac.a0
|
|
||||||
elif ABKG_choice == 3:
|
|
||||||
a_bkg = 77.5 * ac.a0
|
|
||||||
|
|
||||||
#FR resonances
|
|
||||||
#[B11 B12 B2 B3 B4 B51 B52 B53 B6 B71 B72 B81 B82 B83 B9]
|
|
||||||
resonanceB = [1.295, 1.306, 2.174, 2.336, 2.591, 2.74, 2.803, 2.78, 3.357, 4.949, 5.083, 7.172, 7.204, 7.134, 76.9] * u.G #resonance position
|
|
||||||
#[wB11 wB12 wB2 wB3 wB4 wB51 wB52 wB53 wB6 wB71 wB72 wB81 wB82 wB83 wB9]
|
|
||||||
resonancewB = [0.009, 0.010, 0.0005, 0.0005, 0.001, 0.0005, 0.021, 0.015, 0.043, 0.0005, 0.130, 0.024, 0.0005, 0.036, 3.1] * u.G #resonance width
|
|
||||||
|
|
||||||
else: # old values
|
|
||||||
|
|
||||||
if ABKG_choice == 1:
|
|
||||||
a_bkg = 87.2 * ac.a0
|
|
||||||
elif ABKG_choice == 2:
|
|
||||||
a_bkg = 95.2 * ac.a0
|
|
||||||
elif ABKG_choice == 3:
|
|
||||||
a_bkg = 79.2 * ac.a0
|
|
||||||
|
|
||||||
#FR resonances
|
|
||||||
#[B1 B2 B3 B4 B5 B6 B7 B8]
|
|
||||||
resonanceB = [1.298, 2.802, 3.370, 5.092, 7.154, 2.592, 2.338, 2.177] * u.G #resonance position
|
|
||||||
#[wB1 wB2 wB3 wB4 wB5 wB6 wB7 wB8]
|
|
||||||
resonancewB = [0.018, 0.047, 0.048, 0.145, 0.020, 0.008, 0.001, 0.001] * u.G #resonance width
|
|
||||||
|
|
||||||
#Get scattering length
|
|
||||||
np.seterr(divide='ignore')
|
|
||||||
a_s = a_bkg * np.prod([(1 - resonancewB[j] / (B - resonanceB[j])) for j in range(len(resonanceB))])
|
|
||||||
return a_s, a_bkg
|
|
||||||
|
|
||||||
def dipolarLength(mu = DY_DIPOLE_MOMENT, m = DY_MASS):
|
|
||||||
return (m * ac.mu0 * mu**2) / (12 * np.pi * ac.hbar**2)
|
|
||||||
|
|
||||||
def scatteringCrossSection(B):
|
|
||||||
return 8 * np.pi * scatteringLength(B)[0]**2 + ((32*np.pi)/45) * dipolarLength()**2
|
|
||||||
|
|
||||||
def calculateElasticCollisionRate(w_x, w_z, Power, N, T, B): #For a 3D Harmonic Trap
|
|
||||||
return (particleDensity(w_x, w_z, Power, N, T) * scatteringCrossSection(B) * meanThermalVelocity(T) / (2 * np.sqrt(2))).decompose()
|
|
||||||
|
|
||||||
def calculatePSD(w_x, w_z, Power, N, T):
|
|
||||||
return (particleDensity(w_x, w_z, Power, N, T) * thermaldeBroglieWavelength(T)**3).decompose()
|
|
||||||
|
|
||||||
def convert_modulation_depth_to_alpha(modulation_depth):
|
|
||||||
fin_mod_dep = [0, 0.5, 0.3, 0.7, 0.9, 0.8, 1.0, 0.6, 0.4, 0.2, 0.1]
|
|
||||||
fx = [3.135, 0.28, 0.690, 0.152, 0.102, 0.127, 0.099, 0.205, 0.404, 1.441, 2.813]
|
|
||||||
dfx = [0.016, 0.006, 0.005, 0.006, 0.003, 0.002, 0.002,0.002, 0.003, 0.006, 0.024]
|
|
||||||
fz = [2.746, 1.278, 1.719, 1.058, 0.923, 0.994, 0.911, 1.157, 1.446, 2.191, 2.643]
|
|
||||||
dfz = [0.014, 0.007, 0.009, 0.007, 0.005, 0.004, 0.004, 0.005, 0.007, 0.009, 0.033]
|
|
||||||
|
|
||||||
alpha_x = [(fx[0]/x)**(2/3) for x in fx]
|
|
||||||
dalpha_x = [alpha_x[i] * np.sqrt((dfx[0]/fx[0])**2 + (dfx[i]/fx[i])**2) for i in range(len(fx))]
|
|
||||||
alpha_z = [(fz[0]/z)**2 for z in fz]
|
|
||||||
dalpha_z = [alpha_z[i] * np.sqrt((dfz[0]/fz[0])**2 + (dfz[i]/fz[i])**2) for i in range(len(fz))]
|
|
||||||
|
|
||||||
avg_alpha = [(g + h) / 2 for g, h in zip(alpha_x, alpha_z)]
|
|
||||||
sorted_fin_mod_dep, sorted_avg_alpha = zip(*sorted(zip(fin_mod_dep, avg_alpha)))
|
|
||||||
|
|
||||||
f = interpolate.interp1d(sorted_fin_mod_dep, sorted_avg_alpha)
|
|
||||||
|
|
||||||
return f(modulation_depth), fin_mod_dep, alpha_x, alpha_z, dalpha_x, dalpha_z
|
|
||||||
|
|
||||||
def convert_modulation_depth_to_temperature(modulation_depth):
|
|
||||||
fin_mod_dep = [1.0, 0.8, 0.6, 0.4, 0.2, 0.0, 0.9, 0.7, 0.5, 0.3, 0.1]
|
|
||||||
T_x = [22.1, 27.9, 31.7, 42.2, 98.8, 145.8, 27.9, 33.8, 42.4, 61.9, 136.1]
|
|
||||||
dT_x = [1.7, 2.6, 2.4, 3.7, 1.1, 0.6, 2.2, 3.2, 1.7, 2.2, 1.2]
|
|
||||||
T_y = [13.13, 14.75, 18.44, 26.31, 52.55, 92.9, 13.54, 16.11, 21.15, 35.81, 85.8]
|
|
||||||
dT_y = [0.05, 0.05, 0.07, 0.16, 0.28, 0.7, 0.04, 0.07, 0.10, 0.21, 0.8]
|
|
||||||
|
|
||||||
avg_T = [(g + h) / 2 for g, h in zip(T_x, T_y)]
|
|
||||||
sorted_fin_mod_dep, sorted_avg_T = zip(*sorted(zip(fin_mod_dep, avg_T)))
|
|
||||||
|
|
||||||
f = interpolate.interp1d(sorted_fin_mod_dep, sorted_avg_T)
|
|
||||||
|
|
||||||
return f(modulation_depth), fin_mod_dep, T_x, T_y, dT_x, dT_y
|
|
||||||
|
|
||||||
#####################################################################
|
|
||||||
# COMPUTE/EXTRACT TRAP POTENTIAL AND PARAMETERS #
|
|
||||||
#####################################################################
|
|
||||||
|
|
||||||
def trap_depth(w_1, w_2, P, alpha = DY_POLARIZABILITY):
|
|
||||||
return 2*P/(np.pi*w_1*w_2) * (1 / (2 * ac.eps0 * ac.c)) * alpha * (4 * np.pi * ac.eps0 * ac.a0**3)
|
|
||||||
|
|
||||||
def calculateTrapFrequency(w_x, w_z, Power, dir = 'x', m = DY_MASS):
|
|
||||||
TrapDepth = trap_depth(w_x, w_z, Power)
|
|
||||||
TrapFrequency = np.nan
|
|
||||||
if dir == 'x':
|
|
||||||
TrapFrequency = ((1/(2 * np.pi)) * np.sqrt(4 * TrapDepth / (m*w_x**2))).decompose()
|
|
||||||
elif dir == 'y':
|
|
||||||
zReff = np.sqrt(2) * z_R(w_x, 1.064*u.um) * z_R(w_z, 1.064*u.um) / np.sqrt(z_R(w_x, 1.064*u.um)**2 + z_R(w_z, 1.064*u.um)**2)
|
|
||||||
TrapFrequency = ((1/(2 * np.pi)) * np.sqrt(2 * TrapDepth/ (m*zReff**2))).decompose()
|
|
||||||
elif dir == 'z':
|
|
||||||
TrapFrequency = ((1/(2 * np.pi)) * np.sqrt(4 * TrapDepth/ (m*w_z**2))).decompose()
|
|
||||||
return round(TrapFrequency.value, 2)*u.Hz
|
|
||||||
|
|
||||||
def calculateCrossedBeamTrapFrequency(delta, Waists, Powers, dir = 'x', m = DY_MASS, wavelength=1.064*u.um):
|
|
||||||
|
|
||||||
TrapDepth_1 = trap_depth(Waists[0][0], Waists[1][0], Powers[0])
|
|
||||||
TrapDepth_2 = trap_depth(Waists[0][1], Waists[1][1], Powers[1])
|
|
||||||
|
|
||||||
w_x1 = Waists[0][0]
|
|
||||||
w_z1 = Waists[1][0]
|
|
||||||
|
|
||||||
w_y2 = Waists[0][1]
|
|
||||||
w_z2 = Waists[1][1]
|
|
||||||
|
|
||||||
zReff_1 = np.sqrt(2) * z_R(w_x1, wavelength) * z_R(w_z1, wavelength) / np.sqrt(z_R(w_x1, wavelength)**2 + z_R(w_z1, wavelength)**2)
|
|
||||||
zReff_2 = np.sqrt(2) * z_R(w_y2, wavelength) * z_R(w_z2, wavelength) / np.sqrt(z_R(w_y2, wavelength)**2 + z_R(w_z2, wavelength)**2)
|
|
||||||
|
|
||||||
wy2alpha = np.sqrt(((np.cos(np.radians(90 - delta)) / w_y2)**2 + (np.sin(np.radians(90 - delta)) / (2 * zReff_2))**2)**(-1))
|
|
||||||
zR2alpha = np.sqrt(((np.sin(np.radians(90 - delta)) / w_y2)**2 + (np.cos(np.radians(90 - delta)) / (2 * zReff_2))**2)**(-1))
|
|
||||||
|
|
||||||
TrapFrequency = np.nan
|
|
||||||
if dir == 'x':
|
|
||||||
v_1 = (1/(2 * np.pi)) * np.sqrt(4/m * (TrapDepth_1 / w_x1**2))
|
|
||||||
v_2 = (1/(2 * np.pi)) * np.sqrt(4/m * (TrapDepth_2 / zR2alpha**2))
|
|
||||||
TrapFrequency = (np.sqrt(v_1**2 + v_2**2)).decompose()
|
|
||||||
elif dir == 'y':
|
|
||||||
v_1 = (1/(2 * np.pi)) * np.sqrt(1/m * (2 * TrapDepth_1/ zReff_1**2))
|
|
||||||
v_2 = (1/(2 * np.pi)) * np.sqrt(1/m * (4 * TrapDepth_2/ wy2alpha**2))
|
|
||||||
TrapFrequency = (np.sqrt(v_1**2 + v_2**2)).decompose()
|
|
||||||
elif dir == 'z':
|
|
||||||
v_1 = (1/(2 * np.pi)) * np.sqrt(4/m * (TrapDepth_1 / w_z1**2))
|
|
||||||
v_2 = (1/(2 * np.pi)) * np.sqrt(4/m * (TrapDepth_2 / w_z2**2))
|
|
||||||
TrapFrequency = (np.sqrt(v_1**2 + v_2**2)).decompose()
|
|
||||||
|
|
||||||
return round(TrapFrequency.value, 2)*u.Hz
|
|
||||||
|
|
||||||
def extractTrapFrequency(Positions, TrappingPotential, axis):
|
|
||||||
tmp_pos = Positions[axis, :]
|
|
||||||
tmp_pot = TrappingPotential[axis]
|
|
||||||
center_idx = np.argmin(tmp_pot)
|
|
||||||
lb = int(round(center_idx - len(tmp_pot)/200, 1))
|
|
||||||
ub = int(round(center_idx + len(tmp_pot)/200, 1))
|
|
||||||
xdata = tmp_pos[lb:ub]
|
|
||||||
Potential = tmp_pot[lb:ub]
|
|
||||||
p0 = [1e3, tmp_pos[center_idx].value, -100]
|
|
||||||
try:
|
|
||||||
popt, pcov = curve_fit(harmonic_potential, xdata, Potential, p0)
|
|
||||||
v = popt[0]
|
|
||||||
dv = pcov[0][0]**0.5
|
|
||||||
except:
|
|
||||||
popt = np.nan
|
|
||||||
pcov = np.nan
|
|
||||||
v = np.nan
|
|
||||||
dv = np.nan
|
|
||||||
|
|
||||||
return v, dv, popt, pcov
|
|
||||||
|
|
||||||
def computeTrapPotential(w_x, w_z, Power, options):
|
|
||||||
|
|
||||||
axis = options['axis']
|
|
||||||
extent = options['extent']
|
|
||||||
gravity = options['gravity']
|
|
||||||
astigmatism = options['astigmatism']
|
|
||||||
modulation = options['modulation']
|
|
||||||
crossed = options['crossed']
|
|
||||||
|
|
||||||
if modulation:
|
|
||||||
aspect_ratio = options['aspect_ratio']
|
|
||||||
current_ar = w_x/w_z
|
|
||||||
w_x = w_x * (aspect_ratio / current_ar)
|
|
||||||
|
|
||||||
TrappingPotential = []
|
|
||||||
TrapDepth = trap_depth(w_x, w_z, Power)
|
|
||||||
IdealTrapDepthInKelvin = (TrapDepth/ac.k_B).to(u.uK)
|
|
||||||
|
|
||||||
projection_axis = np.array([0, 1, 0]) # default
|
|
||||||
|
|
||||||
if axis == 0:
|
|
||||||
projection_axis = np.array([1, 0, 0]) # radial direction (X-axis)
|
|
||||||
|
|
||||||
elif axis == 1:
|
|
||||||
projection_axis = np.array([0, 1, 0]) # propagation direction (Y-axis)
|
|
||||||
|
|
||||||
elif axis == 2:
|
|
||||||
projection_axis = np.array([0, 0, 1]) # vertical direction (Z-axis)
|
|
||||||
|
|
||||||
else:
|
|
||||||
projection_axis = np.array([1, 1, 1]) # vertical direction (Z-axis)
|
|
||||||
|
|
||||||
x_Positions = np.arange(-extent, extent, 0.05)*u.um
|
|
||||||
y_Positions = np.arange(-extent, extent, 0.05)*u.um
|
|
||||||
z_Positions = np.arange(-extent, extent, 0.05)*u.um
|
|
||||||
Positions = np.vstack((x_Positions, y_Positions, z_Positions)) * projection_axis[:, np.newaxis]
|
|
||||||
|
|
||||||
if not crossed:
|
|
||||||
IdealTrappingPotential = single_gaussian_beam_potential(Positions, np.asarray([w_x.value, w_z.value])*u.um, P = Power)
|
|
||||||
IdealTrappingPotential = IdealTrappingPotential * (np.ones((3, len(IdealTrappingPotential))) * projection_axis[:, np.newaxis])
|
|
||||||
IdealTrappingPotential = (IdealTrappingPotential/ac.k_B).to(u.uK)
|
|
||||||
|
|
||||||
if gravity and not astigmatism:
|
|
||||||
# Influence of Gravity
|
|
||||||
m = DY_MASS
|
|
||||||
gravity_axis = np.array([0, 0, 1])
|
|
||||||
tilt_gravity = options['tilt_gravity']
|
|
||||||
theta = options['theta']
|
|
||||||
tilt_axis = options['tilt_axis']
|
|
||||||
if tilt_gravity:
|
|
||||||
R = rotation_matrix(tilt_axis, np.radians(theta))
|
|
||||||
gravity_axis = np.dot(R, gravity_axis)
|
|
||||||
gravity_axis_positions = np.vstack((x_Positions, y_Positions, z_Positions)) * gravity_axis[:, np.newaxis]
|
|
||||||
TrappingPotential = single_gaussian_beam_potential(Positions, np.asarray([w_x.value, w_z.value])*u.um, P = Power)
|
|
||||||
TrappingPotential = TrappingPotential * (np.ones((3, len(TrappingPotential))) * projection_axis[:, np.newaxis]) + gravitational_potential(gravity_axis_positions, m)
|
|
||||||
TrappingPotential = (TrappingPotential/ac.k_B).to(u.uK)
|
|
||||||
|
|
||||||
elif not gravity and astigmatism:
|
|
||||||
# Influence of Astigmatism
|
|
||||||
foci_disp_single = options['foci_disp_single']
|
|
||||||
TrappingPotential = astigmatic_single_gaussian_beam_potential(Positions, np.asarray([w_x.value, w_z.value])*u.um, P = Power, del_y = foci_disp_single)
|
|
||||||
TrappingPotential = TrappingPotential * (np.ones((3, len(TrappingPotential))) * projection_axis[:, np.newaxis])
|
|
||||||
TrappingPotential = (TrappingPotential/ac.k_B).to(u.uK)
|
|
||||||
|
|
||||||
elif gravity and astigmatism:
|
|
||||||
# Influence of Gravity and Astigmatism
|
|
||||||
m = DY_MASS
|
|
||||||
gravity_axis = np.array([0, 0, 1])
|
|
||||||
tilt_gravity = options['tilt_gravity']
|
|
||||||
theta = options['theta']
|
|
||||||
tilt_axis = options['tilt_axis']
|
|
||||||
foci_disp_single = options['foci_disp_single']
|
|
||||||
if tilt_gravity:
|
|
||||||
R = rotation_matrix(tilt_axis, np.radians(theta))
|
|
||||||
gravity_axis = np.dot(R, gravity_axis)
|
|
||||||
gravity_axis_positions = np.vstack((x_Positions, y_Positions, z_Positions)) * gravity_axis[:, np.newaxis]
|
|
||||||
TrappingPotential = astigmatic_single_gaussian_beam_potential(Positions, np.asarray([w_x.value, w_z.value])*u.um, P = Power, del_y = foci_disp_single)
|
|
||||||
TrappingPotential = TrappingPotential * (np.ones((3, len(TrappingPotential))) * projection_axis[:, np.newaxis]) + gravitational_potential(gravity_axis_positions, m)
|
|
||||||
TrappingPotential = (TrappingPotential/ac.k_B).to(u.uK)
|
|
||||||
|
|
||||||
else:
|
|
||||||
TrappingPotential = IdealTrappingPotential
|
|
||||||
|
|
||||||
infls = np.where(np.diff(np.sign(np.gradient(np.gradient(TrappingPotential[axis].value)))))[0]
|
|
||||||
|
|
||||||
try:
|
|
||||||
if TrappingPotential[axis][0] > TrappingPotential[axis][-1]:
|
|
||||||
EffectiveTrapDepthInKelvin = max(TrappingPotential[axis][infls[1]:-1]) - min(TrappingPotential[axis][infls[0]:infls[1]])
|
|
||||||
elif TrappingPotential[axis][0] < TrappingPotential[axis][-1]:
|
|
||||||
EffectiveTrapDepthInKelvin = max(TrappingPotential[axis][0:infls[0]]) - min(TrappingPotential[axis][infls[0]:infls[1]])
|
|
||||||
else:
|
|
||||||
EffectiveTrapDepthInKelvin = IdealTrapDepthInKelvin
|
|
||||||
except:
|
|
||||||
EffectiveTrapDepthInKelvin = np.nan
|
|
||||||
|
|
||||||
TrapDepthsInKelvin = [IdealTrapDepthInKelvin, EffectiveTrapDepthInKelvin]
|
|
||||||
|
|
||||||
v_x = calculateTrapFrequency(w_x, w_z, Power, dir = 'x')
|
|
||||||
v_y = calculateTrapFrequency(w_x, w_z, Power, dir = 'y')
|
|
||||||
v_z = calculateTrapFrequency(w_x, w_z, Power, dir = 'z')
|
|
||||||
CalculatedTrapFrequencies = [v_x, v_y, v_z]
|
|
||||||
|
|
||||||
v, dv, popt, pcov = extractTrapFrequency(Positions, IdealTrappingPotential, axis)
|
|
||||||
if np.isinf(v):
|
|
||||||
v = np.nan
|
|
||||||
if np.isinf(dv):
|
|
||||||
dv = np.nan
|
|
||||||
|
|
||||||
IdealTrapFrequency = [v, dv]
|
|
||||||
|
|
||||||
if options['extract_trap_frequencies']:
|
|
||||||
v, dv, popt, pcov = extractTrapFrequency(Positions, TrappingPotential, axis)
|
|
||||||
if np.isinf(v):
|
|
||||||
v = np.nan
|
|
||||||
if np.isinf(dv):
|
|
||||||
dv = np.nan
|
|
||||||
TrapFrequency = [v, dv]
|
|
||||||
ExtractedTrapFrequencies = [IdealTrapFrequency, TrapFrequency]
|
|
||||||
else:
|
|
||||||
ExtractedTrapFrequencies = [IdealTrapFrequency]
|
|
||||||
|
|
||||||
return Positions, IdealTrappingPotential, TrappingPotential, TrapDepthsInKelvin, CalculatedTrapFrequencies, ExtractedTrapFrequencies
|
|
||||||
|
|
||||||
else:
|
|
||||||
waists = np.vstack((np.asarray([w_x[0].value, w_z[0].value])*u.um, np.asarray([w_x[1].value, w_z[1].value])*u.um))
|
|
||||||
IdealTrappingPotential = crossed_beam_potential(Positions, waists, Power, options)
|
|
||||||
IdealTrappingPotential = IdealTrappingPotential * (np.ones((3, len(IdealTrappingPotential))) * projection_axis[:, np.newaxis])
|
|
||||||
IdealTrappingPotential = (IdealTrappingPotential/ac.k_B).to(u.uK)
|
|
||||||
|
|
||||||
if gravity and not astigmatism:
|
|
||||||
# Influence of Gravity
|
|
||||||
m = DY_MASS
|
|
||||||
gravity_axis = np.array([0, 0, 1])
|
|
||||||
tilt_gravity = options['tilt_gravity']
|
|
||||||
theta = options['theta']
|
|
||||||
tilt_axis = options['tilt_axis']
|
|
||||||
if tilt_gravity:
|
|
||||||
R = rotation_matrix(tilt_axis, np.radians(theta))
|
|
||||||
gravity_axis = np.dot(R, gravity_axis)
|
|
||||||
gravity_axis_positions = np.vstack((x_Positions, y_Positions, z_Positions)) * gravity_axis[:, np.newaxis]
|
|
||||||
TrappingPotential = crossed_beam_potential(Positions, waists, Power, options)
|
|
||||||
TrappingPotential = TrappingPotential * (np.ones((3, len(TrappingPotential))) * projection_axis[:, np.newaxis]) + gravitational_potential(gravity_axis_positions, m)
|
|
||||||
TrappingPotential = (TrappingPotential/ac.k_B).to(u.uK)
|
|
||||||
|
|
||||||
elif not gravity and astigmatism:
|
|
||||||
# Influence of Astigmatism
|
|
||||||
TrappingPotential = astigmatic_crossed_beam_potential(Positions, waists, Power, options)
|
|
||||||
TrappingPotential = TrappingPotential * (np.ones((3, len(TrappingPotential))) * projection_axis[:, np.newaxis])
|
|
||||||
TrappingPotential = (TrappingPotential/ac.k_B).to(u.uK)
|
|
||||||
|
|
||||||
elif gravity and astigmatism:
|
|
||||||
# Influence of Gravity and Astigmatism
|
|
||||||
m = DY_MASS
|
|
||||||
gravity_axis = np.array([0, 0, 1])
|
|
||||||
tilt_gravity = options['tilt_gravity']
|
|
||||||
theta = options['theta']
|
|
||||||
tilt_axis = options['tilt_axis']
|
|
||||||
if tilt_gravity:
|
|
||||||
R = rotation_matrix(tilt_axis, np.radians(theta))
|
|
||||||
gravity_axis = np.dot(R, gravity_axis)
|
|
||||||
gravity_axis_positions = np.vstack((x_Positions, y_Positions, z_Positions)) * gravity_axis[:, np.newaxis]
|
|
||||||
TrappingPotential = astigmatic_crossed_beam_potential(Positions, waists, Power, options)
|
|
||||||
TrappingPotential = TrappingPotential * (np.ones((3, len(TrappingPotential))) * projection_axis[:, np.newaxis]) + gravitational_potential(gravity_axis_positions, m)
|
|
||||||
TrappingPotential = (TrappingPotential/ac.k_B).to(u.uK)
|
|
||||||
|
|
||||||
else:
|
|
||||||
TrappingPotential = IdealTrappingPotential
|
|
||||||
|
|
||||||
infls = np.where(np.diff(np.sign(np.gradient(np.gradient(TrappingPotential[axis].value)))))[0]
|
|
||||||
|
|
||||||
try:
|
|
||||||
if TrappingPotential[axis][0] > TrappingPotential[axis][-1]:
|
|
||||||
EffectiveTrapDepthInKelvin = max(TrappingPotential[axis][infls[1]:-1]) - min(TrappingPotential[axis][infls[0]:infls[1]])
|
|
||||||
elif TrappingPotential[axis][0] < TrappingPotential[axis][-1]:
|
|
||||||
EffectiveTrapDepthInKelvin = max(TrappingPotential[axis][0:infls[0]]) - min(TrappingPotential[axis][infls[0]:infls[1]])
|
|
||||||
else:
|
|
||||||
EffectiveTrapDepthInKelvin = IdealTrapDepthInKelvin
|
|
||||||
except:
|
|
||||||
EffectiveTrapDepthInKelvin = np.nan
|
|
||||||
|
|
||||||
TrapDepthsInKelvin = [IdealTrapDepthInKelvin, EffectiveTrapDepthInKelvin]
|
|
||||||
|
|
||||||
v_x = calculateCrossedBeamTrapFrequency(options['delta'], [w_x, w_z], Power, dir = 'x')
|
|
||||||
v_y = calculateCrossedBeamTrapFrequency(options['delta'], [w_x, w_z], Power, dir = 'y')
|
|
||||||
v_z = calculateCrossedBeamTrapFrequency(options['delta'], [w_x, w_z], Power, dir = 'z')
|
|
||||||
CalculatedTrapFrequencies = [v_x, v_y, v_z]
|
|
||||||
|
|
||||||
v, dv, popt, pcov = extractTrapFrequency(Positions, IdealTrappingPotential, axis)
|
|
||||||
if np.isinf(v):
|
|
||||||
v = np.nan
|
|
||||||
if np.isinf(dv):
|
|
||||||
dv = np.nan
|
|
||||||
|
|
||||||
IdealTrapFrequency = [v, dv]
|
|
||||||
|
|
||||||
if options['extract_trap_frequencies']:
|
|
||||||
v, dv, popt, pcov = extractTrapFrequency(Positions, TrappingPotential, axis)
|
|
||||||
if np.isinf(v):
|
|
||||||
v = np.nan
|
|
||||||
if np.isinf(dv):
|
|
||||||
dv = np.nan
|
|
||||||
TrapFrequency = [v, dv]
|
|
||||||
ExtractedTrapFrequencies = [IdealTrapFrequency, TrapFrequency]
|
|
||||||
else:
|
|
||||||
ExtractedTrapFrequencies = [IdealTrapFrequency]
|
|
||||||
|
|
||||||
return Positions, IdealTrappingPotential, TrappingPotential, TrapDepthsInKelvin, CalculatedTrapFrequencies, ExtractedTrapFrequencies
|
|
||||||
|
|
||||||
def extractWaist(Positions, TrappingPotential):
|
|
||||||
tmp_pos = Positions.value
|
|
||||||
tmp_pot = TrappingPotential.value
|
|
||||||
center_idx = np.argmin(tmp_pot)
|
|
||||||
|
|
||||||
TrapMinimum = tmp_pot[center_idx]
|
|
||||||
TrapCenter = tmp_pos[center_idx]
|
|
||||||
|
|
||||||
lb = int(round(center_idx - len(tmp_pot)/30, 1))
|
|
||||||
ub = int(round(center_idx + len(tmp_pot)/30, 1))
|
|
||||||
xdata = tmp_pos[lb:ub]
|
|
||||||
Potential = tmp_pot[lb:ub]
|
|
||||||
|
|
||||||
p0=[TrapMinimum, 30, TrapCenter, 0]
|
|
||||||
popt, pcov = curve_fit(gaussian_potential, xdata, Potential, p0)
|
|
||||||
return popt, pcov
|
|
||||||
|
|
||||||
def computeIntensityProfileAndPotentials(Power, waists, wavelength, options, alpha = DY_POLARIZABILITY):
|
|
||||||
w_x = waists[0]
|
|
||||||
w_z = waists[1]
|
|
||||||
extent = options['extent']
|
|
||||||
modulation = options['modulation']
|
|
||||||
mod_func = options['modulation_function']
|
|
||||||
|
|
||||||
if not modulation:
|
|
||||||
extent = 50
|
|
||||||
x_Positions = np.arange(-extent, extent, 1)*u.um
|
|
||||||
y_Positions = np.arange(-extent, extent, 1)*u.um
|
|
||||||
z_Positions = np.arange(-extent, extent, 1)*u.um
|
|
||||||
|
|
||||||
idx = np.where(y_Positions==0)[0][0]
|
|
||||||
|
|
||||||
wavelength = 1.064*u.um
|
|
||||||
|
|
||||||
xm,ym,zm = np.meshgrid(x_Positions, y_Positions, z_Positions, sparse=True, indexing='ij')
|
|
||||||
|
|
||||||
## Single Gaussian Beam
|
|
||||||
A = 2*Power/(np.pi*w(ym, w_x, wavelength)*w(ym, w_z, wavelength))
|
|
||||||
intensity_profile = A * np.exp(-2 * ((xm/w(ym, w_x, wavelength))**2 + (zm/w(ym, w_z, wavelength))**2))
|
|
||||||
I = intensity_profile[:, idx, :].to(u.MW/(u.cm*u.cm))
|
|
||||||
|
|
||||||
U_tilde = (1 / (2 * ac.eps0 * ac.c)) * alpha * (4 * np.pi * ac.eps0 * ac.a0**3)
|
|
||||||
U = - U_tilde * I
|
|
||||||
U = (U/ac.k_B).to(u.uK)
|
|
||||||
|
|
||||||
return [x_Positions, z_Positions], [w_x.value, 0, w_z.value, 0], I, U, [0, 0, 0, 0]
|
|
||||||
|
|
||||||
else:
|
|
||||||
mod_amp = options['modulation_amplitude']
|
|
||||||
x_Positions = np.arange(-extent, extent, 1)*u.um
|
|
||||||
y_Positions = np.arange(-extent, extent, 1)*u.um
|
|
||||||
z_Positions = np.arange(-extent, extent, 1)*u.um
|
|
||||||
|
|
||||||
mod_amp = mod_amp * w_x
|
|
||||||
n_points = len(x_Positions)
|
|
||||||
dx, xmod_Positions = modulation_function(mod_amp, n_points, func = mod_func)
|
|
||||||
|
|
||||||
idx = np.where(y_Positions==0)[0][0]
|
|
||||||
|
|
||||||
xm,ym,zm,xmodm = np.meshgrid(x_Positions, y_Positions, z_Positions, xmod_Positions, sparse=True, indexing='ij')
|
|
||||||
|
|
||||||
## Single Modulated Gaussian Beam
|
|
||||||
A = 2*Power/(np.pi*w(y_Positions[idx] , w_x, wavelength)*w(y_Positions[idx], w_z, wavelength))
|
|
||||||
intensity_profile = A * 1/(2*mod_amp) * np.trapz(np.exp(-2 * (((xmodm - xm)/w(ym, w_x, wavelength))**2 + (zm/w(ym, w_z, wavelength))**2)), dx = dx, axis = -1)
|
|
||||||
I = intensity_profile[:, idx, :].to(u.MW/(u.cm*u.cm))
|
|
||||||
|
|
||||||
U_tilde = (1 / (2 * ac.eps0 * ac.c)) * alpha * (4 * np.pi * ac.eps0 * ac.a0**3)
|
|
||||||
U = - U_tilde * I
|
|
||||||
U = (U/ac.k_B).to(u.uK)
|
|
||||||
|
|
||||||
poptx, pcovx = extractWaist(x_Positions, U[:, np.where(z_Positions==0)[0][0]])
|
|
||||||
poptz, pcovz = extractWaist(z_Positions, U[np.where(x_Positions==0)[0][0], :])
|
|
||||||
|
|
||||||
extracted_waist_x = poptx[1]
|
|
||||||
dextracted_waist_x = pcovx[1][1]**0.5
|
|
||||||
extracted_waist_z = poptz[1]
|
|
||||||
dextracted_waist_z = pcovz[1][1]**0.5
|
|
||||||
|
|
||||||
return [x_Positions, z_Positions], [extracted_waist_x, dextracted_waist_x, extracted_waist_z, dextracted_waist_z], I, U, [poptx, pcovx, poptz, pcovz]
|
|
@ -1,80 +0,0 @@
|
|||||||
import math
|
|
||||||
import numpy as np
|
|
||||||
from scipy import signal
|
|
||||||
from astropy import units as u, constants as ac
|
|
||||||
|
|
||||||
DY_POLARIZABILITY = 184.4 # in a.u, most precise measured value of Dy polarizability
|
|
||||||
DY_MASS = 164*u.u
|
|
||||||
DY_DIPOLE_MOMENT = 9.93 * ac.muB
|
|
||||||
|
|
||||||
#####################################################################
|
|
||||||
# HELPER FUNCTIONS #
|
|
||||||
#####################################################################
|
|
||||||
|
|
||||||
def orderOfMagnitude(number):
|
|
||||||
return math.floor(math.log(number, 10))
|
|
||||||
|
|
||||||
def rotation_matrix(axis, theta):
|
|
||||||
"""
|
|
||||||
Return the rotation matrix associated with counterclockwise rotation about
|
|
||||||
the given axis by theta radians.
|
|
||||||
In 2-D it is just,
|
|
||||||
thetaInRadians = np.radians(theta)
|
|
||||||
c, s = np.cos(thetaInRadians), np.sin(thetaInRadians)
|
|
||||||
R = np.array(((c, -s), (s, c)))
|
|
||||||
In 3-D, one way to do it is use the Euler-Rodrigues Formula as is done here
|
|
||||||
"""
|
|
||||||
axis = np.asarray(axis)
|
|
||||||
axis = axis / math.sqrt(np.dot(axis, axis))
|
|
||||||
a = math.cos(theta / 2.0)
|
|
||||||
b, c, d = -axis * math.sin(theta / 2.0)
|
|
||||||
aa, bb, cc, dd = a * a, b * b, c * c, d * d
|
|
||||||
bc, ad, ac, ab, bd, cd = b * c, a * d, a * c, a * b, b * d, c * d
|
|
||||||
return np.array([[aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac)],
|
|
||||||
[2 * (bc - ad), aa + cc - bb - dd, 2 * (cd + ab)],
|
|
||||||
[2 * (bd + ac), 2 * (cd - ab), aa + dd - bb - cc]])
|
|
||||||
|
|
||||||
def find_nearest(array, value):
|
|
||||||
array = np.asarray(array)
|
|
||||||
idx = (np.abs(array - value)).argmin()
|
|
||||||
return idx
|
|
||||||
|
|
||||||
def modulation_function(mod_amp, n_points, func = 'arccos'):
|
|
||||||
|
|
||||||
if func == 'sin':
|
|
||||||
phi = np.linspace(0, 2*np.pi, n_points)
|
|
||||||
mod_func = mod_amp * np.sin(phi)
|
|
||||||
elif func == 'arccos':
|
|
||||||
# phi = np.linspace(0, 2*np.pi, n_points)
|
|
||||||
# mod_func = mod_amp * (2/np.pi * np.arccos(phi/np.pi-1) - 1)
|
|
||||||
phi = np.linspace(0, 2*np.pi, int(n_points/2))
|
|
||||||
tmp_1 = 2/np.pi * np.arccos(phi/np.pi-1) - 1
|
|
||||||
tmp_2 = np.flip(tmp_1)
|
|
||||||
mod_func = mod_amp * np.concatenate((tmp_1, tmp_2))
|
|
||||||
elif func == 'triangle':
|
|
||||||
phi = np.linspace(0, 2*np.pi, n_points)
|
|
||||||
mod_func = mod_amp * signal.sawtooth(phi, width = 0.5) # width of 0.5 gives symmetric rising triangle ramp
|
|
||||||
elif func == 'square':
|
|
||||||
phi = np.linspace(0, 1.99*np.pi, n_points)
|
|
||||||
mod_func = mod_amp * signal.square(phi, duty = 0.5)
|
|
||||||
else:
|
|
||||||
mod_func = None
|
|
||||||
|
|
||||||
if mod_func is not None:
|
|
||||||
dx = (max(mod_func) - min(mod_func))/(2*n_points)
|
|
||||||
|
|
||||||
return dx, mod_func
|
|
||||||
|
|
||||||
#####################################################################
|
|
||||||
# BEAM PARAMETERS #
|
|
||||||
#####################################################################
|
|
||||||
|
|
||||||
# Rayleigh length
|
|
||||||
def z_R(w_0, lamb)->np.ndarray:
|
|
||||||
return np.pi*w_0**2/lamb
|
|
||||||
|
|
||||||
# Beam Radius
|
|
||||||
def w(pos, w_0, lamb):
|
|
||||||
return w_0*np.sqrt(1+(pos / z_R(w_0, lamb))**2)
|
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
@ -1,346 +0,0 @@
|
|||||||
import numpy as np
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
import matplotlib.ticker as mtick
|
|
||||||
from astropy import units as u, constants as ac
|
|
||||||
|
|
||||||
from Calculator import *
|
|
||||||
from Helpers import *
|
|
||||||
from Potentials import *
|
|
||||||
|
|
||||||
#####################################################################
|
|
||||||
# PLOTTING #
|
|
||||||
#####################################################################
|
|
||||||
|
|
||||||
def generate_label(v, dv):
|
|
||||||
unit = 'Hz'
|
|
||||||
if v <= 0.0:
|
|
||||||
v = np.nan
|
|
||||||
dv = np.nan
|
|
||||||
unit = 'Hz'
|
|
||||||
elif v > 0.0 and orderOfMagnitude(v) > 2:
|
|
||||||
v = v / 1e3 # in kHz
|
|
||||||
dv = dv / 1e3 # in kHz
|
|
||||||
unit = 'kHz'
|
|
||||||
tf_label = '\u03BD = %.1f \u00B1 %.2f %s'% tuple([v,dv,unit])
|
|
||||||
return tf_label
|
|
||||||
|
|
||||||
def plotHarmonicFit(Positions, TrappingPotential, TrapDepthsInKelvin, axis, popt, pcov):
|
|
||||||
v = popt[0]
|
|
||||||
dv = pcov[0][0]**0.5
|
|
||||||
happrox = harmonic_potential(Positions[axis, :].value, *popt)
|
|
||||||
fig = plt.figure(figsize=(12, 6))
|
|
||||||
ax = fig.add_subplot(121)
|
|
||||||
ax.set_title('Fit to Potential')
|
|
||||||
plt.plot(Positions[axis, :].value, happrox, '-r', label = '\u03BD = %.1f \u00B1 %.2f Hz'% tuple([v,dv]))
|
|
||||||
plt.plot(Positions[axis, :], TrappingPotential[axis], 'ob', label = 'Gaussian Potential')
|
|
||||||
plt.xlabel('Distance (um)', fontsize= 12, fontweight='bold')
|
|
||||||
plt.ylabel('Trap Potential (uK)', fontsize= 12, fontweight='bold')
|
|
||||||
plt.ylim([-TrapDepthsInKelvin[0].value, max(TrappingPotential[axis].value)])
|
|
||||||
plt.grid(visible=1)
|
|
||||||
plt.legend(prop={'size': 12, 'weight': 'bold'})
|
|
||||||
|
|
||||||
bx = fig.add_subplot(122)
|
|
||||||
bx.set_title('Fit Residuals')
|
|
||||||
plt.plot(Positions[axis, :].value, TrappingPotential[axis].value - happrox, 'ob')
|
|
||||||
plt.xlabel('Distance (um)', fontsize= 12, fontweight='bold')
|
|
||||||
plt.ylabel('$U_{trap} - U_{Harmonic}$', fontsize= 12, fontweight='bold')
|
|
||||||
plt.xlim([-10, 10])
|
|
||||||
plt.ylim([-1e-2, 1e-2])
|
|
||||||
plt.grid(visible=1)
|
|
||||||
plt.tight_layout()
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
def plotGaussianFit(Positions, TrappingPotential, popt, pcov):
|
|
||||||
extracted_waist = popt[1]
|
|
||||||
dextracted_waist = pcov[1][1]**0.5
|
|
||||||
gapprox = gaussian_potential(Positions, *popt)
|
|
||||||
fig = plt.figure(figsize=(12, 6))
|
|
||||||
ax = fig.add_subplot(121)
|
|
||||||
ax.set_title('Fit to Potential')
|
|
||||||
plt.plot(Positions, gapprox, '-r', label = 'waist = %.1f \u00B1 %.2f um'% tuple([extracted_waist,dextracted_waist]))
|
|
||||||
plt.plot(Positions, TrappingPotential, 'ob', label = 'Gaussian Potential')
|
|
||||||
plt.xlabel('Distance (um)', fontsize= 12, fontweight='bold')
|
|
||||||
plt.ylabel('Trap Potential (uK)', fontsize= 12, fontweight='bold')
|
|
||||||
plt.ylim([min(TrappingPotential), max(TrappingPotential)])
|
|
||||||
plt.grid(visible=1)
|
|
||||||
plt.legend(prop={'size': 12, 'weight': 'bold'})
|
|
||||||
|
|
||||||
bx = fig.add_subplot(122)
|
|
||||||
bx.set_title('Fit Residuals')
|
|
||||||
plt.plot(Positions, TrappingPotential - gapprox, 'ob')
|
|
||||||
plt.xlabel('Distance (um)', fontsize= 12, fontweight='bold')
|
|
||||||
plt.ylabel('$U_{trap} - U_{Gaussian}$', fontsize= 12, fontweight='bold')
|
|
||||||
plt.xlim([-10, 10])
|
|
||||||
plt.ylim([-1, 1])
|
|
||||||
plt.grid(visible=1)
|
|
||||||
plt.tight_layout()
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
def plotPotential(Positions, ComputedPotentials, options, Params = [], listToIterateOver = [], save = False):
|
|
||||||
|
|
||||||
axis = options['axis']
|
|
||||||
|
|
||||||
plt.figure(figsize=(9, 7))
|
|
||||||
for i in range(np.size(ComputedPotentials, 0)):
|
|
||||||
|
|
||||||
if i % 2 == 0:
|
|
||||||
j = int(i / 2)
|
|
||||||
else:
|
|
||||||
j = int((i - 1) / 2)
|
|
||||||
|
|
||||||
IdealTrapDepthInKelvin = Params[j][0][0]
|
|
||||||
EffectiveTrapDepthInKelvin = Params[j][0][1]
|
|
||||||
|
|
||||||
idealv = Params[j][2][0][0]
|
|
||||||
idealdv = Params[j][2][0][1]
|
|
||||||
|
|
||||||
if options['extract_trap_frequencies']:
|
|
||||||
v = Params[j][2][1][0]
|
|
||||||
dv = Params[j][2][1][1]
|
|
||||||
else:
|
|
||||||
v = np.nan
|
|
||||||
dv = np.nan
|
|
||||||
|
|
||||||
if listToIterateOver:
|
|
||||||
if np.size(ComputedPotentials, 0) == len(listToIterateOver):
|
|
||||||
plt.plot(Positions[axis], ComputedPotentials[i][axis], label = 'Trap Depth = ' + str(round(EffectiveTrapDepthInKelvin.value, 2)) + ' ' + str(EffectiveTrapDepthInKelvin.unit) + '; ' + generate_label(v, dv))
|
|
||||||
else:
|
|
||||||
if i % 2 == 0:
|
|
||||||
plt.plot(Positions[axis], ComputedPotentials[i][axis], '--', label = 'Trap Depth = ' + str(round(IdealTrapDepthInKelvin.value, 2)) + ' ' + str(IdealTrapDepthInKelvin.unit) + '; ' + generate_label(idealv, idealdv))
|
|
||||||
elif i % 2 != 0:
|
|
||||||
plt.plot(Positions[axis], ComputedPotentials[i][axis], label = 'Effective Trap Depth = ' + str(round(EffectiveTrapDepthInKelvin.value, 2)) + ' ' + str(EffectiveTrapDepthInKelvin.unit) + '; ' + generate_label(v, dv))
|
|
||||||
else:
|
|
||||||
if i % 2 == 0:
|
|
||||||
plt.plot(Positions[axis], ComputedPotentials[i][axis], '--', label = 'Trap Depth = ' + str(round(IdealTrapDepthInKelvin.value, 2)) + ' ' + str(IdealTrapDepthInKelvin.unit) + '; ' + generate_label(idealv, idealdv))
|
|
||||||
elif i % 2 != 0:
|
|
||||||
plt.plot(Positions[axis], ComputedPotentials[i][axis], label = 'Effective Trap Depth = ' + str(round(EffectiveTrapDepthInKelvin.value, 2)) + ' ' + str(EffectiveTrapDepthInKelvin.unit) + '; ' + generate_label(v, dv))
|
|
||||||
if axis == 0:
|
|
||||||
dir = 'X - Horizontal'
|
|
||||||
elif axis == 1:
|
|
||||||
dir = 'Y - Propagation'
|
|
||||||
else:
|
|
||||||
dir = 'Z - Vertical'
|
|
||||||
|
|
||||||
plt.ylim(top = 0)
|
|
||||||
plt.xlabel(dir + ' Direction (um)', fontsize= 12, fontweight='bold')
|
|
||||||
plt.ylabel('Trap Potential (uK)', fontsize= 12, fontweight='bold')
|
|
||||||
plt.tight_layout()
|
|
||||||
plt.grid(visible=1)
|
|
||||||
plt.legend(loc=3, prop={'size': 12, 'weight': 'bold'})
|
|
||||||
if save:
|
|
||||||
plt.savefig('pot_' + dir + '.png')
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
def plotIntensityProfileAndPotentials(positions, waists, I, U):
|
|
||||||
|
|
||||||
x_Positions = positions[0]
|
|
||||||
z_Positions = positions[1]
|
|
||||||
|
|
||||||
w_x = waists[0]
|
|
||||||
dw_x = waists[1]
|
|
||||||
w_z = waists[2]
|
|
||||||
dw_x = waists[3]
|
|
||||||
|
|
||||||
ar = w_x/w_z
|
|
||||||
dar = ar * np.sqrt((dw_x/w_x)**2 + (dw_x/w_z)**2)
|
|
||||||
|
|
||||||
fig = plt.figure(figsize=(12, 6))
|
|
||||||
ax = fig.add_subplot(121)
|
|
||||||
ax.set_title('Intensity Profile ($MW/cm^2$)\n Aspect Ratio = %.2f \u00B1 %.2f um'% tuple([ar,dar]))
|
|
||||||
im = plt.imshow(np.transpose(I.value), cmap="coolwarm", extent=[np.min(x_Positions.value), np.max(x_Positions.value), np.min(z_Positions.value), np.max(z_Positions.value)])
|
|
||||||
plt.xlabel('X - Horizontal (um)', fontsize= 12, fontweight='bold')
|
|
||||||
plt.ylabel('Z - Vertical (um)', fontsize= 12, fontweight='bold')
|
|
||||||
ax.set_aspect('equal')
|
|
||||||
fig.colorbar(im, fraction=0.046, pad=0.04, orientation='vertical')
|
|
||||||
|
|
||||||
bx = fig.add_subplot(122)
|
|
||||||
bx.set_title('Trap Potential')
|
|
||||||
plt.plot(x_Positions, U[:, np.where(z_Positions==0)[0][0]], label = 'X - Horizontal')
|
|
||||||
plt.plot(z_Positions, U[np.where(x_Positions==0)[0][0], :], label = 'Z - Vertical')
|
|
||||||
plt.ylim(top = 0)
|
|
||||||
plt.xlabel('Extent (um)', fontsize= 12, fontweight='bold')
|
|
||||||
plt.ylabel('Depth (uK)', fontsize= 12, fontweight='bold')
|
|
||||||
plt.tight_layout()
|
|
||||||
plt.grid(visible=1)
|
|
||||||
plt.legend(prop={'size': 12, 'weight': 'bold'})
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
def plotAlphas():
|
|
||||||
|
|
||||||
modulation_depth = np.arange(0, 1.1, 0.1)
|
|
||||||
Alphas, fin_mod_dep, alpha_x, alpha_y, dalpha_x, dalpha_y = convert_modulation_depth_to_alpha(modulation_depth)
|
|
||||||
|
|
||||||
plt.figure()
|
|
||||||
plt.errorbar(fin_mod_dep, alpha_x, yerr = dalpha_x, fmt= 'ob', label = 'From Horz TF', markersize=5, capsize=5)
|
|
||||||
plt.errorbar(fin_mod_dep, alpha_y, yerr = dalpha_y, fmt= 'or', label = 'From Vert TF', markersize=5, capsize=5)
|
|
||||||
plt.plot(modulation_depth, Alphas, '--g')
|
|
||||||
plt.xlabel('Modulation depth', fontsize= 12, fontweight='bold')
|
|
||||||
plt.ylabel('$\\alpha$', fontsize= 12, fontweight='bold')
|
|
||||||
plt.tight_layout()
|
|
||||||
plt.grid(visible=1)
|
|
||||||
plt.legend(prop={'size': 12, 'weight': 'bold'})
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
def plotTemperatures(w_x, w_z, plot_against_mod_depth = True):
|
|
||||||
|
|
||||||
modulation_depth = np.arange(0, 1.1, 0.1)
|
|
||||||
w_xs = w_x * convert_modulation_depth_to_alpha(modulation_depth)[0]
|
|
||||||
new_aspect_ratio = w_xs / w_z
|
|
||||||
Temperatures, fin_mod_dep, T_x, T_y, dT_x, dT_y = convert_modulation_depth_to_temperature(modulation_depth)
|
|
||||||
measured_aspect_ratio = (w_x * convert_modulation_depth_to_alpha(fin_mod_dep)[0]) / w_z
|
|
||||||
|
|
||||||
plt.figure()
|
|
||||||
if plot_against_mod_depth:
|
|
||||||
plt.errorbar(fin_mod_dep, T_x, yerr = dT_x, fmt= 'ob', label = 'Horz direction', markersize=5, capsize=5)
|
|
||||||
plt.errorbar(fin_mod_dep, T_y, yerr = dT_y, fmt= 'or', label = 'Vert direction', markersize=5, capsize=5)
|
|
||||||
plt.plot(modulation_depth, Temperatures, '--g')
|
|
||||||
xlabel = 'Modulation depth'
|
|
||||||
else:
|
|
||||||
plt.errorbar(measured_aspect_ratio, T_x, yerr = dT_x, fmt= 'ob', label = 'Horz direction', markersize=5, capsize=5)
|
|
||||||
plt.errorbar(measured_aspect_ratio, T_y, yerr = dT_y, fmt= 'or', label = 'Vert direction', markersize=5, capsize=5)
|
|
||||||
plt.plot(new_aspect_ratio, Temperatures, '--g')
|
|
||||||
xlabel = 'Aspect Ratio'
|
|
||||||
|
|
||||||
plt.xlabel(xlabel, fontsize= 12, fontweight='bold')
|
|
||||||
plt.ylabel('Temperature (uK)', fontsize= 12, fontweight='bold')
|
|
||||||
plt.tight_layout()
|
|
||||||
plt.grid(visible=1)
|
|
||||||
plt.legend(prop={'size': 12, 'weight': 'bold'})
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
def plotTrapFrequencies(v_x, v_y, v_z, modulation_depth, new_aspect_ratio, plot_against_mod_depth = True):
|
|
||||||
fig, ax3 = plt.subplots(figsize=(8, 6))
|
|
||||||
|
|
||||||
if plot_against_mod_depth:
|
|
||||||
ln1 = ax3.plot(modulation_depth, v_x, '-or', label = 'v_x')
|
|
||||||
ln2 = ax3.plot(modulation_depth, v_z, '-^b', label = 'v_z')
|
|
||||||
ax4 = ax3.twinx()
|
|
||||||
ln3 = ax4.plot(modulation_depth, v_y, '-*g', label = 'v_y')
|
|
||||||
xlabel = 'Modulation depth'
|
|
||||||
else:
|
|
||||||
ln1 = ax3.plot(new_aspect_ratio, v_x, '-or', label = 'v_x')
|
|
||||||
ln2 = ax3.plot(new_aspect_ratio, v_z, '-^b', label = 'v_z')
|
|
||||||
ax4 = ax3.twinx()
|
|
||||||
ln3 = ax4.plot(new_aspect_ratio, v_y, '-*g', label = 'v_y')
|
|
||||||
xlabel = 'Aspect Ratio'
|
|
||||||
|
|
||||||
ax3.set_xlabel(xlabel, fontsize= 12, fontweight='bold')
|
|
||||||
ax3.set_ylabel('Trap Frequency (Hz)', fontsize= 12, fontweight='bold')
|
|
||||||
ax3.tick_params(axis="y", labelcolor='b')
|
|
||||||
ax4.set_ylabel('Trap Frequency (Hz)', fontsize= 12, fontweight='bold')
|
|
||||||
ax4.tick_params(axis="y", labelcolor='g')
|
|
||||||
plt.tight_layout()
|
|
||||||
plt.grid(visible=1)
|
|
||||||
lns = ln1+ln2+ln3
|
|
||||||
labs = [l.get_label() for l in lns]
|
|
||||||
ax3.legend(lns, labs, prop={'size': 12, 'weight': 'bold'})
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
def plotMeasuredTrapFrequencies(fx, dfx, fy, dfy, fz, dfz, modulation_depth_radial, modulation_depth_axial, w_x, w_z, plot_against_mod_depth = True):
|
|
||||||
|
|
||||||
alpha_x = [(fx[0]/x)**(2/3) for x in fx]
|
|
||||||
dalpha_x = [alpha_x[i] * np.sqrt((dfx[0]/fx[0])**2 + (dfx[i]/fx[i])**2) for i in range(len(fx))]
|
|
||||||
alpha_y = [(fy[0]/y)**2 for y in fy]
|
|
||||||
dalpha_y = [alpha_y[i] * np.sqrt((dfy[0]/fy[0])**2 + (dfy[i]/fy[i])**2) for i in range(len(fy))]
|
|
||||||
|
|
||||||
avg_alpha = [(g + h) / 2 for g, h in zip(alpha_x, alpha_y)]
|
|
||||||
new_aspect_ratio = (w_x * avg_alpha) / w_z
|
|
||||||
|
|
||||||
|
|
||||||
if plot_against_mod_depth:
|
|
||||||
fig, ax1 = plt.subplots(figsize=(8, 6))
|
|
||||||
ax2 = ax1.twinx()
|
|
||||||
ax1.errorbar(modulation_depth_radial, fx, yerr = dfx, fmt= 'or', label = 'v_x', markersize=5, capsize=5)
|
|
||||||
ax2.errorbar(modulation_depth_axial, fy, yerr = dfy, fmt= '*g', label = 'v_y', markersize=5, capsize=5)
|
|
||||||
ax1.errorbar(modulation_depth_radial, fz, yerr = dfz, fmt= '^b', label = 'v_z', markersize=5, capsize=5)
|
|
||||||
ax1.set_xlabel('Modulation depth', fontsize= 12, fontweight='bold')
|
|
||||||
ax1.set_ylabel('Trap Frequency (kHz)', fontsize= 12, fontweight='bold')
|
|
||||||
ax1.tick_params(axis="y", labelcolor='b')
|
|
||||||
ax2.set_ylabel('Trap Frequency (Hz)', fontsize= 12, fontweight='bold')
|
|
||||||
ax2.tick_params(axis="y", labelcolor='g')
|
|
||||||
h1, l1 = ax1.get_legend_handles_labels()
|
|
||||||
h2, l2 = ax2.get_legend_handles_labels()
|
|
||||||
ax1.legend(h1+h2, l1+l2, loc=0, prop={'size': 12, 'weight': 'bold'})
|
|
||||||
else:
|
|
||||||
plt.figure()
|
|
||||||
plt.errorbar(new_aspect_ratio, fx, yerr = dfx, fmt= 'or', label = 'v_x', markersize=5, capsize=5)
|
|
||||||
plt.errorbar(new_aspect_ratio, fz, yerr = dfz, fmt= '^b', label = 'v_z', markersize=5, capsize=5)
|
|
||||||
plt.xlabel('Aspect Ratio', fontsize= 12, fontweight='bold')
|
|
||||||
plt.ylabel('Trap Frequency (kHz)', fontsize= 12, fontweight='bold')
|
|
||||||
plt.legend(prop={'size': 12, 'weight': 'bold'})
|
|
||||||
|
|
||||||
plt.tight_layout()
|
|
||||||
plt.grid(visible=1)
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
def plotRatioOfTrapFrequencies(fx, fy, fz, dfx, dfy, dfz, v_x, v_y, v_z, modulation_depth, w_x, w_z, plot_against_mod_depth = True):
|
|
||||||
|
|
||||||
w_xs = w_x * convert_modulation_depth_to_alpha(modulation_depth)[0]
|
|
||||||
new_aspect_ratio = w_xs / w_z
|
|
||||||
|
|
||||||
plt.figure()
|
|
||||||
|
|
||||||
if plot_against_mod_depth:
|
|
||||||
plt.errorbar(modulation_depth, fx/v_x, yerr = dfx/v_x, fmt= 'or', label = 'b/w horz TF', markersize=5, capsize=5)
|
|
||||||
plt.errorbar(modulation_depth, fy/v_y, yerr = dfy/v_y, fmt= '*g', label = 'b/w axial TF', markersize=5, capsize=5)
|
|
||||||
plt.errorbar(modulation_depth, fz/v_z, yerr = dfz/v_z, fmt= '^b', label = 'b/w vert TF', markersize=5, capsize=5)
|
|
||||||
xlabel = 'Modulation depth'
|
|
||||||
else:
|
|
||||||
plt.errorbar(new_aspect_ratio, fx/v_x, yerr = dfx/v_x, fmt= 'or', label = 'b/w horz TF', markersize=5, capsize=5)
|
|
||||||
plt.errorbar(new_aspect_ratio, fy/v_y, yerr = dfy/v_y, fmt= '*g', label = 'b/w axial TF', markersize=5, capsize=5)
|
|
||||||
plt.errorbar(new_aspect_ratio, fz/v_z, yerr = dfz/v_z, fmt= '^b', label = 'b/w vert TF', markersize=5, capsize=5)
|
|
||||||
xlabel = 'Aspect Ratio'
|
|
||||||
|
|
||||||
plt.xlabel(xlabel, fontsize= 12, fontweight='bold')
|
|
||||||
plt.ylabel('Ratio', fontsize= 12, fontweight='bold')
|
|
||||||
plt.tight_layout()
|
|
||||||
plt.grid(visible=1)
|
|
||||||
plt.legend(prop={'size': 12, 'weight': 'bold'})
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
def plotScatteringLengths(B_range = [0, 2.59]):
|
|
||||||
BField = np.arange(B_range[0], B_range[1], 1e-3) * u.G
|
|
||||||
a_s_array = np.zeros(len(BField)) * ac.a0
|
|
||||||
for idx in range(len(BField)):
|
|
||||||
a_s_array[idx], a_bkg = scatteringLength(BField[idx])
|
|
||||||
rmelmIdx = [i for i, x in enumerate(np.isinf(a_s_array.value)) if x]
|
|
||||||
for x in rmelmIdx:
|
|
||||||
a_s_array[x-1] = np.inf * ac.a0
|
|
||||||
|
|
||||||
plt.figure(figsize=(9, 7))
|
|
||||||
plt.plot(BField, a_s_array/ac.a0, '-b')
|
|
||||||
plt.axhline(y = a_bkg/ac.a0, color = 'r', linestyle = '--')
|
|
||||||
plt.text(min(BField.value) + 0.5, (a_bkg/ac.a0).value + 1, '$a_{bkg}$ = %.2f a0' %((a_bkg/ac.a0).value), fontsize=14, fontweight='bold')
|
|
||||||
plt.xlim([min(BField.value), max(BField.value)])
|
|
||||||
plt.ylim([65, 125])
|
|
||||||
plt.xlabel('B field (G)', fontsize= 12, fontweight='bold')
|
|
||||||
plt.ylabel('Scattering length (a0)', fontsize= 12, fontweight='bold')
|
|
||||||
plt.tight_layout()
|
|
||||||
plt.grid(visible=1)
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
def plotCollisionRatesAndPSD(Gamma_elastic, PSD, modulation_depth, new_aspect_ratio, plot_against_mod_depth = True):
|
|
||||||
fig, ax1 = plt.subplots(figsize=(8, 6))
|
|
||||||
ax2 = ax1.twinx()
|
|
||||||
|
|
||||||
if plot_against_mod_depth:
|
|
||||||
ax1.plot(modulation_depth, Gamma_elastic, '-ob')
|
|
||||||
ax2.plot(modulation_depth, PSD, '-*r')
|
|
||||||
ax2.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1e'))
|
|
||||||
xlabel = 'Modulation depth'
|
|
||||||
else:
|
|
||||||
ax1.plot(new_aspect_ratio, Gamma_elastic, '-ob')
|
|
||||||
ax2.plot(new_aspect_ratio, PSD, '-*r')
|
|
||||||
ax2.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1e'))
|
|
||||||
xlabel = 'Aspect Ratio'
|
|
||||||
|
|
||||||
ax1.set_xlabel(xlabel, fontsize= 12, fontweight='bold')
|
|
||||||
ax1.set_ylabel('Elastic Collision Rate', fontsize= 12, fontweight='bold')
|
|
||||||
ax1.tick_params(axis="y", labelcolor='b')
|
|
||||||
ax2.set_ylabel('Phase Space Density', fontsize= 12, fontweight='bold')
|
|
||||||
ax2.tick_params(axis="y", labelcolor='r')
|
|
||||||
plt.tight_layout()
|
|
||||||
plt.grid(visible=1)
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
#####################################################################
|
|
@ -1,107 +0,0 @@
|
|||||||
import numpy as np
|
|
||||||
from astropy import units as u, constants as ac
|
|
||||||
|
|
||||||
from Helpers import *
|
|
||||||
|
|
||||||
DY_POLARIZABILITY = 184.4 # in a.u, most precise measured value of Dy polarizability
|
|
||||||
DY_MASS = 164*u.u
|
|
||||||
DY_DIPOLE_MOMENT = 9.93 * ac.muB
|
|
||||||
|
|
||||||
#####################################################################
|
|
||||||
# POTENTIALS #
|
|
||||||
#####################################################################
|
|
||||||
|
|
||||||
def gravitational_potential(positions, m):
|
|
||||||
return m * ac.g0 * positions
|
|
||||||
|
|
||||||
def single_gaussian_beam_potential(positions, waists, alpha = DY_POLARIZABILITY, P=1, wavelength=1.064*u.um):
|
|
||||||
A = 2*P/(np.pi*w(positions[1,:], waists[0], wavelength)*w(positions[1,:], waists[1], wavelength))
|
|
||||||
U_tilde = (1 / (2 * ac.eps0 * ac.c)) * alpha * (4 * np.pi * ac.eps0 * ac.a0**3)
|
|
||||||
U = - U_tilde * A * np.exp(-2 * ((positions[0,:]/w(positions[1,:], waists[0], wavelength))**2 + (positions[2,:]/w(positions[1,:], waists[1], wavelength))**2))
|
|
||||||
return U
|
|
||||||
|
|
||||||
def astigmatic_single_gaussian_beam_potential(positions, waists, del_y, alpha = DY_POLARIZABILITY, P=1, wavelength=1.064*u.um):
|
|
||||||
A = 2*P/(np.pi*w(positions[1,:] - (del_y/2), waists[0], wavelength)*w(positions[1,:] + (del_y/2), waists[1], wavelength))
|
|
||||||
U_tilde = (1 / (2 * ac.eps0 * ac.c)) * alpha * (4 * np.pi * ac.eps0 * ac.a0**3)
|
|
||||||
U = - U_tilde * A * np.exp(-2 * ((positions[0,:]/w(positions[1,:] - (del_y/2), waists[0], wavelength))**2 + (positions[2,:]/w(positions[1,:] + (del_y/2), waists[1], wavelength))**2))
|
|
||||||
return U
|
|
||||||
|
|
||||||
def modulated_single_gaussian_beam_potential(positions, waists, alpha = DY_POLARIZABILITY, P=1, wavelength=1.064*u.um, mod_amp=1):
|
|
||||||
mod_amp = mod_amp * waists[0]
|
|
||||||
n_points = len(positions[0,:])
|
|
||||||
dx, x_mod = modulation_function(mod_amp, n_points, func = 'arccos')
|
|
||||||
A = 2*P/(np.pi*w(positions[1,:], waists[0], wavelength)*w(positions[1,:], waists[1], wavelength))
|
|
||||||
U_tilde = (1 / (2 * ac.eps0 * ac.c)) * alpha * (4 * np.pi * ac.eps0 * ac.a0**3)
|
|
||||||
dU = np.zeros(2*n_points)
|
|
||||||
for i in range(len(x_mod)):
|
|
||||||
dU = np.vstack((dU, np.exp(-2 * (np.subtract(x_mod[i], positions[0,:])/w(positions[1,:], waists[0], wavelength))**2)))
|
|
||||||
U = - U_tilde * A * 1/(2*mod_amp) * np.trapz(dU, dx = dx, axis = 0)
|
|
||||||
return U
|
|
||||||
|
|
||||||
def harmonic_potential(pos, v, xoffset, yoffset, m = DY_MASS):
|
|
||||||
U_Harmonic = ((0.5 * m * (2 * np.pi * v*u.Hz)**2 * (pos*u.um - xoffset*u.um)**2)/ac.k_B).to(u.uK) + yoffset*u.uK
|
|
||||||
return U_Harmonic.value
|
|
||||||
|
|
||||||
def gaussian_potential(pos, amp, waist, xoffset, yoffset):
|
|
||||||
U_Gaussian = amp * np.exp(-2 * ((pos + xoffset) / waist)**2) + yoffset
|
|
||||||
return U_Gaussian
|
|
||||||
|
|
||||||
def crossed_beam_potential(positions, waists, P, options, alpha = DY_POLARIZABILITY, wavelength=1.064*u.um):
|
|
||||||
|
|
||||||
delta = options['delta']
|
|
||||||
|
|
||||||
foci_shift = options['foci_shift']
|
|
||||||
focus_shift_beam_1 = foci_shift[0]
|
|
||||||
focus_shift_beam_2 = foci_shift[1]
|
|
||||||
|
|
||||||
beam_disp = options['beam_disp']
|
|
||||||
beam_1_disp = (np.ones(np.shape(positions.T)) * np.array(beam_disp[0])).T * beam_disp[0].unit
|
|
||||||
beam_2_disp = (np.ones(np.shape(positions.T)) * np.array(beam_disp[1])).T * beam_disp[1].unit
|
|
||||||
|
|
||||||
beam_1_positions = positions + beam_1_disp
|
|
||||||
A_1 = 2*P[0]/(np.pi*w(beam_1_positions[1,:] + focus_shift_beam_1, waists[0][0], wavelength)*w(beam_1_positions[1,:] + focus_shift_beam_1, waists[0][1], wavelength))
|
|
||||||
U_1_tilde = (1 / (2 * ac.eps0 * ac.c)) * alpha * (4 * np.pi * ac.eps0 * ac.a0**3)
|
|
||||||
U_1 = - U_1_tilde * A_1 * np.exp(-2 * ((beam_1_positions[0,:]/w(beam_1_positions[1,:] + focus_shift_beam_1, waists[0][0], wavelength))**2 + (beam_1_positions[2,:]/w(beam_1_positions[1,:] + focus_shift_beam_1, waists[0][1], wavelength))**2))
|
|
||||||
|
|
||||||
R = rotation_matrix([0, 0, 1], np.radians(delta))
|
|
||||||
beam_2_positions = np.dot(R, positions + beam_2_disp)
|
|
||||||
A_2 = 2*P[1]/(np.pi*w(beam_2_positions[1,:] + focus_shift_beam_2, waists[1][0], wavelength)*w(beam_2_positions[1,:] + focus_shift_beam_2, waists[1][1], wavelength))
|
|
||||||
U_2_tilde = (1 / (2 * ac.eps0 * ac.c)) * alpha * (4 * np.pi * ac.eps0 * ac.a0**3)
|
|
||||||
U_2 = - U_2_tilde * A_2 * np.exp(-2 * ((beam_2_positions[0,:]/w(beam_2_positions[1,:] + focus_shift_beam_2, waists[1][0], wavelength))**2 + (beam_2_positions[2,:]/w(beam_2_positions[1,:] + focus_shift_beam_2, waists[1][1], wavelength))**2))
|
|
||||||
|
|
||||||
U = U_1 + U_2
|
|
||||||
|
|
||||||
return U
|
|
||||||
|
|
||||||
def astigmatic_crossed_beam_potential(positions, waists, P, options, alpha = DY_POLARIZABILITY, wavelength=1.064*u.um):
|
|
||||||
|
|
||||||
delta = options['delta']
|
|
||||||
|
|
||||||
del_y = options['foci_disp_crossed']
|
|
||||||
del_y_1 = del_y[0]
|
|
||||||
del_y_2 = del_y[1]
|
|
||||||
|
|
||||||
|
|
||||||
foci_shift = options['foci_shift']
|
|
||||||
focus_shift_beam_1 = foci_shift[0]
|
|
||||||
focus_shift_beam_2 = foci_shift[1]
|
|
||||||
|
|
||||||
beam_disp = options['beam_disp']
|
|
||||||
beam_1_disp = (np.ones(np.shape(positions.T)) * np.array(beam_disp[0])).T * beam_disp[0].unit
|
|
||||||
beam_2_disp = (np.ones(np.shape(positions.T)) * np.array(beam_disp[1])).T * beam_disp[1].unit
|
|
||||||
|
|
||||||
beam_1_positions = positions + beam_1_disp
|
|
||||||
A_1 = 2*P[0]/(np.pi*w(beam_1_positions[1,:] - (del_y_1/2) + focus_shift_beam_1, waists[0][0], wavelength)*w(beam_1_positions[1,:] + (del_y_1/2) + focus_shift_beam_1, waists[0][1], wavelength))
|
|
||||||
U_1_tilde = (1 / (2 * ac.eps0 * ac.c)) * alpha * (4 * np.pi * ac.eps0 * ac.a0**3)
|
|
||||||
U_1 = - U_1_tilde * A_1 * np.exp(-2 * ((beam_1_positions[0,:]/w(beam_1_positions[1,:] - (del_y_1/2) + focus_shift_beam_1, waists[0][0], wavelength))**2 + (beam_1_positions[2,:]/w(beam_1_positions[1,:] + (del_y_1/2) + focus_shift_beam_1, waists[0][1], wavelength))**2))
|
|
||||||
|
|
||||||
R = rotation_matrix([0, 0, 1], np.radians(delta))
|
|
||||||
beam_2_positions = np.dot(R, positions + beam_2_disp)
|
|
||||||
A_2 = 2*P[1]/(np.pi*w(beam_2_positions[1,:] - (del_y_2/2) + focus_shift_beam_2, waists[1][0], wavelength)*w(beam_2_positions[1,:] + (del_y_2/2) + focus_shift_beam_2, waists[1][1], wavelength))
|
|
||||||
U_2_tilde = (1 / (2 * ac.eps0 * ac.c)) * alpha * (4 * np.pi * ac.eps0 * ac.a0**3)
|
|
||||||
U_2 = - U_2_tilde * A_2 * np.exp(-2 * ((beam_2_positions[0,:]/w(beam_2_positions[1,:] - (del_y_2/2) + focus_shift_beam_2, waists[1][0], wavelength))**2 + (beam_2_positions[2,:]/w(beam_2_positions[1,:] + (del_y_2/2) + focus_shift_beam_2, waists[1][1], wavelength))**2))
|
|
||||||
|
|
||||||
U = U_1 + U_2
|
|
||||||
|
|
||||||
return U
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
|||||||
import numpy as np
|
|
||||||
import pyfits
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
import skimage
|
|
||||||
from skimage.feature import blob_dog, blob_doh, blob_log, canny
|
|
||||||
from skimage.color import rgb2gray
|
|
||||||
from skimage.feature import corner_harris, corner_subpix, corner_peaks
|
|
||||||
from skimage.segmentation import slic
|
|
||||||
from skimage.filters import sobel
|
|
||||||
from scipy.signal import convolve2d
|
|
||||||
|
|
||||||
from scipy.ndimage import gaussian_filter
|
|
||||||
from skimage import measure
|
|
||||||
from scipy.optimize import curve_fit
|
|
||||||
import matplotlib.ticker as mtick
|
|
||||||
from scipy.signal import savgol_filter
|
|
||||||
|
|
||||||
import scipy
|
|
||||||
from scipy import signal
|
|
||||||
from scipy.signal import argrelextrema
|
|
||||||
|
|
||||||
|
|
||||||
import cv2
|
|
||||||
|
|
||||||
## this function will get the values along each circle. We start by defining a range of angles, computing the
|
|
||||||
#coordinates and then finding the values at the nearest pixel position.
|
|
||||||
def get_line(star,theta,radius,x_c,y_c):
|
|
||||||
#theta = np.linspace(0,2*np.pi,N_theta)
|
|
||||||
x = x_c + radius*np.cos(theta)
|
|
||||||
y = y_c + radius*np.sin(theta)
|
|
||||||
x = np.round(x)
|
|
||||||
y = np.round(y)
|
|
||||||
x = x.astype(int)
|
|
||||||
y = y.astype(int)
|
|
||||||
I = star[y,x]
|
|
||||||
|
|
||||||
return I,x,y
|
|
||||||
|
|
||||||
## a function to compute the frequecy for a certain radius
|
|
||||||
def get_radius(freq):
|
|
||||||
N_p = 36
|
|
||||||
r = N_p/(2*np.pi*freq)
|
|
||||||
return r
|
|
||||||
|
|
||||||
## a function to compute the radius for a certain frequency
|
|
||||||
def get_freq(radius):
|
|
||||||
N_p = 36
|
|
||||||
freq = N_p/(2*np.pi*radius)
|
|
||||||
return freq
|
|
||||||
|
|
||||||
def sinusoidal(theta,a,b,c):
|
|
||||||
N_p = 36
|
|
||||||
y = a + b*np.sin(N_p*theta) + c*np.cos(N_p*theta)
|
|
||||||
return y
|
|
||||||
|
|
||||||
def fit_sinusoid(I,theta,p0):
|
|
||||||
popt, pcov = curve_fit(sinusoidal,theta,I,p0)
|
|
||||||
a = popt[0]
|
|
||||||
b = popt[1]
|
|
||||||
c = popt[2]
|
|
||||||
modulation = np.sqrt(b**2 + c**2)/a
|
|
||||||
return modulation, popt
|
|
||||||
|
|
||||||
def Gaussian(x,a,x0,sigma):
|
|
||||||
y = a*(1/(np.sqrt(2*np.pi)*sigma))*np.exp(-(x-x0)**2/(2*sigma**2))
|
|
||||||
#y = np.exp(-2*(np.pi**2)*((x-x0)**2)*sigma**2)
|
|
||||||
return y
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user