Script to estimate trap frequencies of the hybrid trap of AL, cODT.
This commit is contained in:
parent
a3899a7827
commit
750bd1bf69
368
Estimations/EstimatesForHybridTrap.m
Normal file
368
Estimations/EstimatesForHybridTrap.m
Normal file
@ -0,0 +1,368 @@
|
|||||||
|
%% Physical constants
|
||||||
|
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;
|
||||||
|
VacuumPermittivity = 1 / (SpeedOfLight^2 * VacuumPermeability);
|
||||||
|
HartreeEnergy = ElectronCharge^2 / (4 * pi * VacuumPermittivity * BohrRadius);
|
||||||
|
AtomicUnitOfPolarizability = (ElectronCharge^2 * BohrRadius^2) / HartreeEnergy; % Or simply 4*pi*VacuumPermittivity*BohrRadius^3
|
||||||
|
|
||||||
|
% Dy specific constants
|
||||||
|
Dy164Mass = 163.929174751*AtomicMassUnit;
|
||||||
|
Dy164IsotopicAbundance = 0.2826;
|
||||||
|
DyMagneticMoment = 9.93*BohrMagneton;
|
||||||
|
|
||||||
|
%% Helper Functions
|
||||||
|
|
||||||
|
function R = rotation_matrix(axis, theta)
|
||||||
|
% rotation_matrix returns the 3x3 rotation matrix associated with
|
||||||
|
% counterclockwise rotation about the given axis by theta radians.
|
||||||
|
|
||||||
|
% Normalize the axis
|
||||||
|
axis = axis / sqrt(dot(axis, axis));
|
||||||
|
|
||||||
|
% Compute the rotation matrix components
|
||||||
|
a = cos(theta / 2.0);
|
||||||
|
b = -axis(1) * sin(theta / 2.0);
|
||||||
|
c = -axis(2) * sin(theta / 2.0);
|
||||||
|
d = -axis(3) * sin(theta / 2.0);
|
||||||
|
|
||||||
|
% Precompute terms for readability
|
||||||
|
aa = a * a; bb = b * b; cc = c * c; dd = d * d;
|
||||||
|
bc = b * c; ad = a * d; ac = a * c; ab = a * b;
|
||||||
|
bd = b * d; cd = c * d;
|
||||||
|
|
||||||
|
% Construct the rotation matrix
|
||||||
|
R = [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];
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Potentials
|
||||||
|
|
||||||
|
function U_gravity = gravitational_potential(positions, m)
|
||||||
|
g = 9.81; % Earth's gravitational constant
|
||||||
|
U = m * g * positions;
|
||||||
|
end
|
||||||
|
|
||||||
|
function U_Harmonic = harmonic_potential(pos, v, xoffset, yoffset, m)
|
||||||
|
% Calculate the harmonic potential
|
||||||
|
k_B = physical_constant('Boltzmann constant');
|
||||||
|
Hz = 1; % for unit Hz
|
||||||
|
U_Harmonic = ((0.5 * m * (2 * pi * v * Hz).^2 * (pos - xoffset).^2) / k_B) + yoffset;
|
||||||
|
end
|
||||||
|
|
||||||
|
function U_crossedodt = crossed_beam_potential(positions, waists, P, options, alpha)
|
||||||
|
% Crossed beam potential
|
||||||
|
if nargin < 5
|
||||||
|
alpha = 184.4; % Dy polarizability default
|
||||||
|
end
|
||||||
|
wavelength = 1.064e-6; % wavelength in meters
|
||||||
|
|
||||||
|
delta = options.delta;
|
||||||
|
foci_shift = options.foci_shift;
|
||||||
|
focus_shift_beam_1 = foci_shift(1);
|
||||||
|
focus_shift_beam_2 = foci_shift(2);
|
||||||
|
|
||||||
|
beam_disp = options.beam_disp;
|
||||||
|
beam_1_disp = beam_disp(1);
|
||||||
|
beam_2_disp = beam_disp(2);
|
||||||
|
|
||||||
|
beam_1_positions = positions + beam_1_disp;
|
||||||
|
A_1 = 2 * P(1) ./ (pi * w(beam_1_positions(2,:) + focus_shift_beam_1, waists(1,1), wavelength) ...
|
||||||
|
.* w(beam_1_positions(2,:) + focus_shift_beam_1, waists(1,2), wavelength));
|
||||||
|
U_1_tilde = (1 / (2 * 8.854e-12 * 3e8)) * alpha * (4 * pi * 8.854e-12 * 5.29177e-11^3);
|
||||||
|
U_1 = -U_1_tilde * A_1 .* exp(-2 * ((beam_1_positions(1,:) ./ w(beam_1_positions(2,:) + focus_shift_beam_1, waists(1,1), wavelength)).^2 ...
|
||||||
|
+ (beam_1_positions(3,:) ./ w(beam_1_positions(2,:) + focus_shift_beam_1, waists(1,2), wavelength)).^2));
|
||||||
|
|
||||||
|
R = rotation_matrix([0, 0, 1], deg2rad(delta));
|
||||||
|
beam_2_positions = R * (positions + beam_2_disp);
|
||||||
|
A_2 = 2 * P(2) ./ (pi * w(beam_2_positions(2,:) + focus_shift_beam_2, waists(2,1), wavelength) ...
|
||||||
|
.* w(beam_2_positions(2,:) + focus_shift_beam_2, waists(2,2), wavelength));
|
||||||
|
U_2_tilde = (1 / (2 * 8.854e-12 * 3e8)) * alpha * (4 * pi * 8.854e-12 * 5.29177e-11^3);
|
||||||
|
U_2 = -U_2_tilde * A_2 .* exp(-2 * ((beam_2_positions(1,:) ./ w(beam_2_positions(2,:) + focus_shift_beam_2, waists(2,1), wavelength)).^2 ...
|
||||||
|
+ (beam_2_positions(3,:) ./ w(beam_2_positions(2,:) + focus_shift_beam_2, waists(2,2), wavelength)).^2));
|
||||||
|
|
||||||
|
U = U_1 + U_2;
|
||||||
|
end
|
||||||
|
|
||||||
|
function U_astigcrossedodt = astigmatic_crossed_beam_potential(positions, waists, P, options, alpha, wavelength)
|
||||||
|
% ASTIGMATIC_CROSSED_BEAM_POTENTIAL - Calculate the potential of an astigmatic crossed beam trap.
|
||||||
|
%
|
||||||
|
% U = ASTIGMATIC_CROSSED_BEAM_POTENTIAL(positions, waists, P, options, alpha, wavelength)
|
||||||
|
%
|
||||||
|
% Parameters:
|
||||||
|
% positions - 3xN matrix of positions for the particle/atom.
|
||||||
|
% waists - 2x2 cell array of beam waists, where each element is a 2-element vector [waist_x, waist_y].
|
||||||
|
% P - 1x2 array of powers for the two beams.
|
||||||
|
% options - Struct containing options:
|
||||||
|
% - delta: Angle between beams in degrees.
|
||||||
|
% - foci_disp_crossed: Displacement in the y-direction for both beams [del_y_1, del_y_2].
|
||||||
|
% - foci_shift: Foci shifts for both beams [shift_1, shift_2].
|
||||||
|
% - beam_disp: Displacement for both beams.
|
||||||
|
% alpha - Polarizability of the atom/particle.
|
||||||
|
% wavelength- Wavelength of the beams.
|
||||||
|
%
|
||||||
|
% Returns:
|
||||||
|
% U - The total potential at the given positions.
|
||||||
|
|
||||||
|
if nargin < 5
|
||||||
|
alpha = DY_POLARIZABILITY;
|
||||||
|
end
|
||||||
|
if nargin < 6
|
||||||
|
wavelength = 1.064 * 1e-6; % Default wavelength in meters (1.064 um)
|
||||||
|
end
|
||||||
|
|
||||||
|
delta = options.delta;
|
||||||
|
|
||||||
|
del_y = options.foci_disp_crossed;
|
||||||
|
del_y_1 = del_y(1);
|
||||||
|
del_y_2 = del_y(2);
|
||||||
|
|
||||||
|
foci_shift = options.foci_shift;
|
||||||
|
focus_shift_beam_1 = foci_shift(1);
|
||||||
|
focus_shift_beam_2 = foci_shift(2);
|
||||||
|
|
||||||
|
beam_disp = options.beam_disp;
|
||||||
|
beam_1_disp = repmat(beam_disp{1}, 1, size(positions, 2));
|
||||||
|
beam_2_disp = repmat(beam_disp{2}, 1, size(positions, 2));
|
||||||
|
|
||||||
|
% Calculate beam 1 potential
|
||||||
|
beam_1_positions = positions + beam_1_disp;
|
||||||
|
A_1 = 2*P(1) / (pi * w(beam_1_positions(2,:) - (del_y_1/2) + focus_shift_beam_1, waists{1}(1), wavelength) ...
|
||||||
|
* w(beam_1_positions(2,:) + (del_y_1/2) + focus_shift_beam_1, waists{1}(2), wavelength));
|
||||||
|
U_1_tilde = (1 / (2 * eps0 * c)) * alpha * (4 * pi * eps0 * a0^3);
|
||||||
|
U_1 = - U_1_tilde * A_1 .* exp(-2 * ((beam_1_positions(1,:) ./ w(beam_1_positions(2,:) - (del_y_1/2) + focus_shift_beam_1, waists{1}(1), wavelength)).^2 ...
|
||||||
|
+ (beam_1_positions(3,:) ./ w(beam_1_positions(2,:) + (del_y_1/2) + focus_shift_beam_1, waists{1}(2), wavelength)).^2));
|
||||||
|
|
||||||
|
% Rotation matrix for beam 2
|
||||||
|
R = rotation_matrix([0, 0, 1], deg2rad(delta));
|
||||||
|
beam_2_positions = R * (positions + beam_2_disp);
|
||||||
|
|
||||||
|
% Calculate beam 2 potential
|
||||||
|
A_2 = 2*P(2) / (pi * w(beam_2_positions(2,:) - (del_y_2/2) + focus_shift_beam_2, waists{2}(1), wavelength) ...
|
||||||
|
* w(beam_2_positions(2,:) + (del_y_2/2) + focus_shift_beam_2, waists{2}(2), wavelength));
|
||||||
|
U_2_tilde = (1 / (2 * eps0 * c)) * alpha * (4 * pi * eps0 * a0^3);
|
||||||
|
U_2 = - U_2_tilde * A_2 .* exp(-2 * ((beam_2_positions(1,:) ./ w(beam_2_positions(2,:) - (del_y_2/2) + focus_shift_beam_2, waists{2}(1), wavelength)).^2 ...
|
||||||
|
+ (beam_2_positions(3,:) ./ w(beam_2_positions(2,:) + (del_y_2/2) + focus_shift_beam_2, waists{2}(2), wavelength)).^2));
|
||||||
|
|
||||||
|
% Total potential
|
||||||
|
U = U_1 + U_2;
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Estimators
|
||||||
|
|
||||||
|
function depth = trap_depth(w_1, w_2, P, alpha)
|
||||||
|
% Constants
|
||||||
|
if nargin < 4
|
||||||
|
alpha = DY_POLARIZABILITY; % Default polarizability if not provided
|
||||||
|
end
|
||||||
|
|
||||||
|
% Define constants
|
||||||
|
eps0 = 8.854187817e-12; % Permittivity of free space (F/m)
|
||||||
|
c = 299792458; % Speed of light in vacuum (m/s)
|
||||||
|
a0 = 5.29177210903e-11; % Bohr radius (m)
|
||||||
|
|
||||||
|
% Calculate the trap depth
|
||||||
|
depth = (2 * P) / (pi * w_1 * w_2) * (1 / (2 * eps0 * c)) * alpha * (4 * pi * eps0 * a0^3);
|
||||||
|
end
|
||||||
|
|
||||||
|
function [v, dv, popt, pcov] = extractTrapFrequency(Positions, TrappingPotential, axis)
|
||||||
|
% EXTRACTTRAPFREQUENCY - Extract the trapping frequency by fitting a harmonic potential.
|
||||||
|
%
|
||||||
|
% [v, dv, popt, pcov] = EXTRACTTRAPFREQUENCY(Positions, TrappingPotential, axis)
|
||||||
|
%
|
||||||
|
% Parameters:
|
||||||
|
% Positions - 2D matrix containing the positions of the atoms/particles.
|
||||||
|
% TrappingPotential - Vector containing the potential values for the corresponding positions.
|
||||||
|
% axis - Index of the axis (1, 2, or 3) to extract the frequency.
|
||||||
|
%
|
||||||
|
% Returns:
|
||||||
|
% v - Extracted trapping frequency.
|
||||||
|
% dv - Error/uncertainty in the frequency.
|
||||||
|
% popt - Optimized parameters from the curve fitting.
|
||||||
|
% pcov - Covariance matrix from the curve fitting.
|
||||||
|
|
||||||
|
tmp_pos = Positions(axis, :);
|
||||||
|
tmp_pot = TrappingPotential(axis, :);
|
||||||
|
|
||||||
|
% Find the index of the potential's minimum (trap center)
|
||||||
|
[~, center_idx] = min(tmp_pot);
|
||||||
|
|
||||||
|
% Define a range around the center for fitting (1/100th of the total length)
|
||||||
|
lb = round(center_idx - length(tmp_pot)/200);
|
||||||
|
ub = round(center_idx + length(tmp_pot)/200);
|
||||||
|
|
||||||
|
% Ensure boundaries are valid
|
||||||
|
lb = max(lb, 1); % Lower bound cannot be less than 1
|
||||||
|
ub = min(ub, length(tmp_pot)); % Upper bound cannot exceed length
|
||||||
|
|
||||||
|
% Extract the subset of position and potential data around the center
|
||||||
|
xdata = tmp_pos(lb:ub);
|
||||||
|
Potential = tmp_pot(lb:ub);
|
||||||
|
|
||||||
|
% Initial guess for fitting parameters [v, x0, amplitude]
|
||||||
|
p0 = [1e3, tmp_pos(center_idx), -100];
|
||||||
|
|
||||||
|
% Perform curve fitting using harmonic potential
|
||||||
|
try
|
||||||
|
% Define harmonic potential function (anonymous function)
|
||||||
|
harmonic_potential = @(p, x) p(3) + 0.5 * p(1) * (x - p(2)).^2;
|
||||||
|
|
||||||
|
% Fit the potential data to the harmonic potential model
|
||||||
|
[popt, ~, pcov] = lsqcurvefit(harmonic_potential, p0, xdata, Potential);
|
||||||
|
|
||||||
|
v = popt(1); % Extract fitted frequency
|
||||||
|
dv = sqrt(pcov(1, 1)); % Uncertainty in the frequency
|
||||||
|
catch
|
||||||
|
% In case of fitting failure, return NaNs
|
||||||
|
popt = NaN;
|
||||||
|
pcov = NaN;
|
||||||
|
v = NaN;
|
||||||
|
dv = NaN;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function [Positions, IdealTrappingPotential, TrappingPotential, TrapDepthsInKelvin, ExtractedTrapFrequencies] = computeTrapPotential(w_x, w_z, Power, options)
|
||||||
|
|
||||||
|
% Unpack the options structure
|
||||||
|
axis = options.axis;
|
||||||
|
extent = options.extent;
|
||||||
|
gravity = options.gravity;
|
||||||
|
astigmatism = options.astigmatism;
|
||||||
|
modulation = options.modulation;
|
||||||
|
|
||||||
|
% Apply modulation if necessary
|
||||||
|
if modulation
|
||||||
|
aspect_ratio = options.aspect_ratio;
|
||||||
|
current_ar = w_x / w_z;
|
||||||
|
w_x = w_x * (aspect_ratio / current_ar);
|
||||||
|
end
|
||||||
|
|
||||||
|
% Compute ideal trap depth
|
||||||
|
TrapDepth = trap_depth(w_x, w_z, Power);
|
||||||
|
IdealTrapDepthInKelvin = TrapDepth / ac.k_B * u.uK; % Conversion to uK
|
||||||
|
|
||||||
|
% Default projection axis
|
||||||
|
projection_axis = [0; 1; 0]; % Default Y-axis
|
||||||
|
|
||||||
|
% Set projection axis based on the given axis option
|
||||||
|
if axis == 0
|
||||||
|
projection_axis = [1; 0; 0]; % X-axis
|
||||||
|
elseif axis == 1
|
||||||
|
projection_axis = [0; 1; 0]; % Y-axis
|
||||||
|
elseif axis == 2
|
||||||
|
projection_axis = [0; 0; 1]; % Z-axis
|
||||||
|
else
|
||||||
|
projection_axis = [1; 1; 1]; % Diagonal
|
||||||
|
end
|
||||||
|
|
||||||
|
% Define positions along the specified extent
|
||||||
|
x_Positions = (-extent:0.05:extent) * u.um;
|
||||||
|
y_Positions = (-extent:0.05:extent) * u.um;
|
||||||
|
z_Positions = (-extent:0.05:extent) * u.um;
|
||||||
|
|
||||||
|
% Stack positions along the projection axis
|
||||||
|
Positions = [x_Positions; y_Positions; z_Positions] .* projection_axis;
|
||||||
|
|
||||||
|
% Define the waists for the beams
|
||||||
|
waists = [w_x(1), w_z(1); w_x(2), w_z(2)] * u.um;
|
||||||
|
|
||||||
|
% Calculate the ideal trapping potential
|
||||||
|
IdealTrappingPotential = crossed_beam_potential(Positions, waists, Power, options);
|
||||||
|
IdealTrappingPotential = IdealTrappingPotential .* (ones(3, length(IdealTrappingPotential)) .* projection_axis);
|
||||||
|
IdealTrappingPotential = IdealTrappingPotential / ac.k_B * u.uK; % Convert to uK
|
||||||
|
|
||||||
|
% Initialize the TrappingPotential variable
|
||||||
|
TrappingPotential = [];
|
||||||
|
|
||||||
|
% Handle different combinations of gravity and astigmatism
|
||||||
|
if gravity && ~astigmatism
|
||||||
|
% Gravity effect only
|
||||||
|
m = DY_MASS;
|
||||||
|
gravity_axis = [0; 0; 1]; % Z-axis for gravity
|
||||||
|
if options.tilt_gravity
|
||||||
|
R = rotation_matrix(options.tilt_axis, deg2rad(options.theta));
|
||||||
|
gravity_axis = R * gravity_axis;
|
||||||
|
end
|
||||||
|
gravity_axis_positions = [x_Positions; y_Positions; z_Positions] .* gravity_axis;
|
||||||
|
TrappingPotential = crossed_beam_potential(Positions, waists, Power, options);
|
||||||
|
TrappingPotential = TrappingPotential .* (ones(3, length(TrappingPotential)) .* projection_axis) + gravitational_potential(gravity_axis_positions, m);
|
||||||
|
TrappingPotential = TrappingPotential / ac.k_B * u.uK; % Convert to uK
|
||||||
|
|
||||||
|
elseif ~gravity && astigmatism
|
||||||
|
% Astigmatism effect only
|
||||||
|
TrappingPotential = astigmatic_crossed_beam_potential(Positions, waists, Power, options);
|
||||||
|
TrappingPotential = TrappingPotential .* (ones(3, length(TrappingPotential)) .* projection_axis);
|
||||||
|
TrappingPotential = TrappingPotential / ac.k_B * u.uK; % Convert to uK
|
||||||
|
|
||||||
|
elseif gravity && astigmatism
|
||||||
|
% Both gravity and astigmatism
|
||||||
|
m = DY_MASS;
|
||||||
|
gravity_axis = [0; 0; 1]; % Z-axis for gravity
|
||||||
|
if options.tilt_gravity
|
||||||
|
R = rotation_matrix(options.tilt_axis, deg2rad(options.theta));
|
||||||
|
gravity_axis = R * gravity_axis;
|
||||||
|
end
|
||||||
|
gravity_axis_positions = [x_Positions; y_Positions; z_Positions] .* gravity_axis;
|
||||||
|
TrappingPotential = astigmatic_crossed_beam_potential(Positions, waists, Power, options);
|
||||||
|
TrappingPotential = TrappingPotential .* (ones(3, length(TrappingPotential)) .* projection_axis) + gravitational_potential(gravity_axis_positions, m);
|
||||||
|
TrappingPotential = TrappingPotential / ac.k_B * u.uK; % Convert to uK
|
||||||
|
|
||||||
|
else
|
||||||
|
% Default to ideal trapping potential
|
||||||
|
TrappingPotential = IdealTrappingPotential;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Calculate inflection points and effective trap depth
|
||||||
|
infls = find(diff(sign(gradient(gradient(TrappingPotential(axis,:))))));
|
||||||
|
|
||||||
|
try
|
||||||
|
if TrappingPotential(axis, 1) > TrappingPotential(axis, end)
|
||||||
|
EffectiveTrapDepthInKelvin = max(TrappingPotential(axis, infls(2):end)) - min(TrappingPotential(axis, infls(1):infls(2)));
|
||||||
|
elseif TrappingPotential(axis, 1) < TrappingPotential(axis, end)
|
||||||
|
EffectiveTrapDepthInKelvin = max(TrappingPotential(axis, 1:infls(1))) - min(TrappingPotential(axis, infls(1):infls(2)));
|
||||||
|
else
|
||||||
|
EffectiveTrapDepthInKelvin = IdealTrapDepthInKelvin;
|
||||||
|
end
|
||||||
|
catch
|
||||||
|
EffectiveTrapDepthInKelvin = NaN;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Trap depths in Kelvin
|
||||||
|
TrapDepthsInKelvin = [IdealTrapDepthInKelvin, EffectiveTrapDepthInKelvin];
|
||||||
|
|
||||||
|
% Extract trap frequencies from the ideal trapping potential
|
||||||
|
[v, dv, popt, pcov] = extractTrapFrequency(Positions, IdealTrappingPotential, axis);
|
||||||
|
if isinf(v), v = NaN; end
|
||||||
|
if isinf(dv), dv = NaN; end
|
||||||
|
IdealTrapFrequency = [v, dv];
|
||||||
|
|
||||||
|
% Extract trap frequencies from the actual trapping potential
|
||||||
|
if options.extract_trap_frequencies
|
||||||
|
[v, dv, popt, pcov] = extractTrapFrequency(Positions, TrappingPotential, axis);
|
||||||
|
if isinf(v), v = NaN; end
|
||||||
|
if isinf(dv), dv = NaN; end
|
||||||
|
TrapFrequency = [v, dv];
|
||||||
|
ExtractedTrapFrequencies = {IdealTrapFrequency, TrapFrequency};
|
||||||
|
else
|
||||||
|
ExtractedTrapFrequencies = {IdealTrapFrequency};
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user