Calculations/Dipolar-Gas-Simulator/+Scripts/selectPhaseDiagramPoints.m

100 lines
3.6 KiB
Matlab

function selectPhaseDiagramPoints(PhaseDiagramMatrix, NumberOfAtoms, ScatteringLengths, savePath)
% Interactive point selector for phase diagram.
% - Single click to select a point (plotted in red)
% - Double click to remove nearest point
% - Save points to a MAT file using savePath
xlen = length(NumberOfAtoms);
ylen = length(ScatteringLengths);
selectedIndices = [];
selectedValues = [];
plottedPoints = []; % handles of plotted markers
% Create figure and axes
fig = figure('Name', 'Interactive Phase Diagram', 'Position', [100, 100, 1600, 900]);
ax = axes(fig);
imagesc(ax, PhaseDiagramMatrix);
set(ax, 'YDir', 'normal');
colormap(ax, parula);
colorbar(ax);
axis(ax, 'equal', 'tight');
hold(ax, 'on'); % This is crucial!
% Style
set(ax, 'FontSize', 16, 'Box', 'On', 'Linewidth', 2);
xticks(ax, 1:xlen);
yticks(ax, 1:ylen);
xticklabels(ax, string(NumberOfAtoms));
yticklabels(ax, string(ScatteringLengths));
xlabel(ax, 'Number of Atoms', 'FontSize', 16);
ylabel(ax, 'Scattering Length (\times a_o)', 'FontSize', 16);
grid(ax, 'on');
% Save Button
uicontrol('Style', 'pushbutton', ...
'String', 'Save Points', ...
'FontSize', 12, ...
'Position', [20 20 120 40], ...
'Callback', @savePoints);
% Set callback on axes, not on image
fig.WindowButtonDownFcn = @handleClick;
selectedIndices = zeros(0, 2); % ← ensure it's Nx2, not just []
selectedValues = zeros(0, 2);
plottedPoints = gobjects(0); % empty graphics array
function handleClick(~, ~)
try
clickType = get(fig, 'SelectionType');
cp = get(ax, 'CurrentPoint');
xClick = round(cp(1, 1));
yClick = round(cp(1, 2));
if xClick < 1 || xClick > xlen || yClick < 1 || yClick > ylen
return;
end
if strcmp(clickType, 'normal') % Single click = add point
alreadySelected = any(ismember(selectedIndices, [xClick, yClick], 'rows'));
if ~alreadySelected
selectedIndices(end+1, :) = [xClick, yClick];
selectedValues(end+1, :) = [NumberOfAtoms(xClick), ScatteringLengths(yClick)];
h = plot(ax, xClick, yClick, 'r*', 'MarkerSize', 10, 'LineWidth', 1.5);
plottedPoints(end+1) = h;
fprintf('Selected: N = %.2f, a = %.2f\n', NumberOfAtoms(xClick), ScatteringLengths(yClick));
end
elseif strcmp(clickType, 'open') % Double click = remove point
if isempty(selectedIndices), return; end
dists = vecnorm(selectedIndices - [xClick, yClick], 2, 2);
[minDist, idx] = min(dists);
if minDist <= 1
fprintf('Removed: N = %.2f, a = %.2f\n', selectedValues(idx,1), selectedValues(idx,2));
delete(plottedPoints(idx));
selectedIndices(idx, :) = [];
selectedValues(idx, :) = [];
plottedPoints(idx) = [];
end
end
catch ME
fprintf('Error in handleClick:\n%s\n', getReport(ME, 'extended'));
end
end
function savePoints(~, ~)
if isempty(selectedValues)
warndlg('No points selected.', 'Save Warning');
return;
end
SelectedPoints.indices = selectedIndices;
SelectedPoints.values = selectedValues;
save(savePath, 'SelectedPoints');
msgbox(sprintf('Saved %d points to:\n%s', size(selectedValues,1), savePath), 'Saved');
end
end