function [Positions, IdealTrappingPotential, TrappingPotential, TrapDepthsInKelvin, ExtractedTrapFrequencies] = computeTrapPotential(options)
    
    alpha       = options.Polarizability;

    % Unpack the options struct
    axis        = options.Axis;
    extent      = options.Extent;
    gravity     = options.Gravity;
    astigmatism = options.Astigmatism;
    modulation  = options.Modulation;
    crossed     = options.Crossed;

    Power = options.Power;
    w_x   = options.w_x;
    w_z   = options.w_z;
    
    % Apply modulation if necessary
    if modulation
        aspect_ratio = options.AspectRatio;
        current_ar   = w_x / w_z;
        w_x          = w_x * (aspect_ratio / current_ar);
    end
    
    % Compute ideal trap depth
    TrapDepth              = Calculator.computeTrapDepth(w_x, w_z, Power, alpha);
    IdealTrapDepthInKelvin = (TrapDepth / physconst('boltzmann')) * 1E6; 
    
    % Default projection axis
    projection_axis = [0; 1; 0]; % Default Y-axis

    % Set projection axis based on the given axis option
    if axis == 1
        projection_axis = [1; 0; 0]; % X-axis
    elseif axis == 2
        projection_axis = [0; 1; 0]; % Y-axis
    elseif axis == 3
        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) * 1E-6;
    y_Positions = (-extent:0.05:extent) * 1E-6;
    z_Positions = (-extent:0.05:extent) * 1E-6;
    
    % Stack positions along the projection axis
    Positions = [x_Positions; y_Positions; z_Positions] .* projection_axis;
    
    % Define the waists for the beams
    if crossed
        Waists = [w_x(1), w_z(1); w_x(2), w_z(2)];
        IdealTrappingPotential = Potentials.generateCrossedBeamPotential(Positions, Waists, Power, options); % Calculate the ideal trapping potential
    elseif modulation
        Waists = [w_x, w_z];
        IdealTrappingPotential = Potentials.generateModulatedSingleGaussianBeamPotential(Positions, Waists, Power, options);
    else 
        Waists = [w_x, w_z];
        IdealTrappingPotential = Potentials.generateSingleGaussianBeamPotential(Positions, Waists, Power, options);
    end
    
    IdealTrappingPotential = IdealTrappingPotential .* (ones(3, length(IdealTrappingPotential)) .* projection_axis);
    IdealTrappingPotential = (IdealTrappingPotential / physconst('boltzmann')) * 1E6; % Convert to uK
    
    % Initialize the TrappingPotential variable
    TrappingPotential = [];
    
    % Handle different combinations of gravity and astigmatism
    if gravity && ~astigmatism
        % Gravity effect only
        m = options.Mass;
        gravity_axis = [0; 0; 1]; % Z-axis for gravity
        if options.TiltGravity
            R = Helpers.generateRotationMatrix(options.tilt_axis, deg2rad(options.theta));
            gravity_axis = R * gravity_axis;
        end
        gravity_axis_positions = [x_Positions; y_Positions; z_Positions] .* gravity_axis;
        if crossed
            TrappingPotential = Potentials.generateCrossedBeamPotential(Positions, Waists, Power, options);
        elseif modulation
            TrappingPotential = Potentials.generateModulatedSingleGaussianBeamPotential(Positions, Waists, Power, options);
        else
            TrappingPotential = Potentials.generateSingleGaussianBeamPotential(Positions, Waists, Power, options);
        end
        TrappingPotential = TrappingPotential .* (ones(3, length(TrappingPotential)) .* projection_axis) + Potentials.generateGravitationalPotential(gravity_axis_positions, m);
        TrappingPotential = (TrappingPotential / physconst('boltzmann')) * 1E6; % Convert to uK

    elseif ~gravity && astigmatism
        % Astigmatism effect only
        if crossed
            TrappingPotential = Potentials.generateAstigmaticCrossedBeamPotential(Positions, Waists, Power, options);
        else
            TrappingPotential = Potentials.generateAstigmaticSingleGaussianBeamPotential(Positions, Waists, Power, options);
        end
        TrappingPotential = TrappingPotential .* (ones(3, length(TrappingPotential)) .* projection_axis);
        TrappingPotential = (TrappingPotential / physconst('boltzmann')) * 1E6; % Convert to uK

    elseif gravity && astigmatism
        % Both gravity and astigmatism
        m = options.Mass;
        gravity_axis = [0; 0; 1]; % Z-axis for gravity
        if options.TiltGravity
            R = Helpers.generateRotationMatrix(options.tilt_axis, deg2rad(options.theta));
            gravity_axis = R * gravity_axis;
        end
        gravity_axis_positions = [x_Positions; y_Positions; z_Positions] .* gravity_axis;
        if crossed
            TrappingPotential = Potentials.generateAstigmaticCrossedBeamPotential(Positions, Waists, Power, options);
        else
            TrappingPotential = Potentials.generateAstigmaticSingleGaussianBeamPotential(Positions, Waists, Power, options);
        end
        TrappingPotential = TrappingPotential .* (ones(3, length(TrappingPotential)) .* projection_axis) + Potentials.generateGravitationalPotential(gravity_axis_positions, m);
        TrappingPotential = (TrappingPotential / physconst('boltzmann')) * 1E-6; % 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] = Calculator.extractTrapFrequency(Positions, IdealTrappingPotential, options);
    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.ExtractTrapFrequencies
        [v, dv] = Calculator.extractTrapFrequency(Positions, TrappingPotential, options);
        if isinf(v), v = NaN; end
        if isinf(dv), dv = NaN; end
        TrapFrequency = [v, dv];
        ExtractedTrapFrequencies = {IdealTrapFrequency, TrapFrequency};
    else
        ExtractedTrapFrequencies = {IdealTrapFrequency};
    end

end
