Skip to content

Commit 023d340

Browse files
committed
Add bidirectional scanning phase delay as input argument. BUGFIX: use the actual sampling rate when calculating stuff, not the desired sampling rate.
1 parent bd66a9f commit 023d340

File tree

2 files changed

+38
-21
lines changed

2 files changed

+38
-21
lines changed

completed/private/plotImageData.m

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function plotImageData(imData,h,saveFname,scanPattern)
1+
function plotImageData(imData,h,saveFname,bidiPhaseDelay)
22
%Plot (and optionally save) data produced by scanAndAcquire_Polished
33
%
44
% function plotImageData(imData,h,saveFname,scanPattern)
@@ -15,44 +15,52 @@ function plotImageData(imData,h,saveFname,scanPattern)
1515
% h - plot handles structure produced by scanAndAcquire_Polished
1616
% saveFname - [string] the relative or absolute path of a file to which data should be saved.
1717
% If empty, no data are saved.
18-
% scanPattern - [string] Either 'uni' or 'bidi' depending on the scan pattern used.
18+
% bidiPhaseDelay - [optional] If missing or empty, we assume the images are acquired using a uni-directional
19+
% scan pattern. If bidiPhaseDelay is present, it is a scalar used to correct the phase
20+
% offset between the outgoing and return scanlines.
1921
%
2022
%
2123
% Rob Campbell - Basel 2016
2224

25+
if nargin<4
26+
bidiPhaseDelay=[];
27+
end
2328

2429
imSize = size(get(h(1).hAx,'CData'),1);
2530

2631
%The number of points on one line (larger then imSize if fillFraction < 1)
2732
pointsPerLine = ceil(size(imData,1) / imSize);
2833

2934
timeStamp = now*60^2*24*1E3; %MATLAB serial date in ms. This is used for saving.
30-
35+
36+
%The analog input range is in the CLIM property of the image axes
37+
AI_range = get(h(1).imAx,'CLim');
38+
AI_range = AI_range(2);
39+
3140
for chan = 1:size(imData,2)
3241

3342
im = reshape(imData(:,chan), pointsPerLine, imSize);
3443
im = -rot90(im);
3544

3645
%Remove the turn-around artefact
37-
switch lower(scanPattern)
38-
case 'bidi'
39-
%Flip the even rows if data were acquired bidirectionally
40-
im(2:2:end,:) = fliplr(im(2:2:end,:));
46+
if ~isempty(bidiPhaseDelay)
47+
%Flip the even rows if data were acquired bidirectionally
48+
im(2:2:end,:) = fliplr(im(2:2:end,:));
4149

42-
phaseShift=26; %TODO: put this elsewhere!
43-
im(1:2:end,:) = circshift(im(1:2:end,:),-phaseShift,2);
44-
im(2:2:end,:) = circshift(im(2:2:end,:), phaseShift,2);
50+
im(1:2:end,:) = circshift(im(1:2:end,:),-bidiPhaseDelay,2);
51+
im(2:2:end,:) = circshift(im(2:2:end,:), bidiPhaseDelay,2);
4552

46-
im = fliplr(im); %To keep it in the same orientation as the uni-directional scan
53+
im = fliplr(im); %To keep it in the same orientation as the uni-directional scan
4754

48-
im = im(:,1+phaseShift:end-phaseShift); %Trim the turnaround on one edge (BADLY)
49-
case 'uni'
50-
im = im(:,end-imSize+1:end); %Trim the turnaround on one edge
55+
im = im(:,1+bidiPhaseDelay:end-bidiPhaseDelay); %Trim the turnaround on one edge (BADLY)
56+
set(h(chan).imAx,'XLim',[1,size(im,2)]);
57+
else
58+
im = im(:,end-imSize+1:end); %Trim the turnaround on one edge
5159
end
5260

5361
%Update image
5462
set(h(chan).hAx,'CData',im);
55-
set(h(chan).imAx,'CLim',[0,2],'XLim',[1,size(im,2)]); %TODO: This is potentially a problem point should we choose to use a different digitisation range
63+
5664

5765

5866
if h(chan).histAx ~= 0
@@ -62,7 +70,7 @@ function plotImageData(imData,h,saveFname,scanPattern)
6270
%Keep the axes of the histogram looking nice
6371
set(h(chan).histAx, ...
6472
'YTick', [], ...
65-
'XLim', [-0.1,2], ... %TODO: This is potentially a problem point should we choose to use a different digitisation range
73+
'XLim', [-0.1,AI_range], ...
6674
'Color', 'None', ...
6775
'Box', 'Off');
6876

completed/scanAndAcquire_Polished.m

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ function scanAndAcquire_Polished(hardwareDeviceID,varargin)
2727
% 'samplesPerPixel' - Number of samples per pixel. [4 by default]
2828
% 'scanPattern' - A string defining whether we do uni or bidirectional scanning: 'uni' or 'bidi'
2929
% 'uni' by default
30+
% 'bidiPhase' - a scalar that defines the offset in pixels between the outgoing and return lines
31+
% in bidirectional scanning. 26 by default. This parameter needs changing often and is sensitive.
3032
% 'enableHist' - A boolean. True by default. If true, overlays an intensity histogram on top of the image.
3133
%
3234
%
@@ -83,6 +85,7 @@ function scanAndAcquire_Polished(hardwareDeviceID,varargin)
8385
params.addParameter('sampleRate', 512E3, @(x) isnumeric(x) && isscalar(x));
8486
params.addParameter('fillFraction', 0.9, @(x) isnumeric(x) && isscalar(x));
8587
params.addParameter('scanPattern', 'uni', @(x) ischar(x));
88+
params.addParameter('bidiPhase', 26, @(x) isnumeric(x) && isscalar(x));
8689
params.addParameter('enableHist', true, @(x) islogical (x) || x==0 || x==1);
8790

8891
%Process the input arguments in varargin using the inputParser object we just built
@@ -97,7 +100,12 @@ function scanAndAcquire_Polished(hardwareDeviceID,varargin)
97100
sampleRate = params.Results.sampleRate;
98101
fillFraction = params.Results.fillFraction;
99102
scanPattern = params.Results.scanPattern;
103+
bidiPhase = params.Results.bidiPhase;
100104
enableHist = params.Results.enableHist;
105+
106+
if ~strcmpi(scanPattern,'bidi')
107+
bidiPhase=[];
108+
end
101109
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
102110

103111

@@ -129,12 +137,12 @@ function scanAndAcquire_Polished(hardwareDeviceID,varargin)
129137
% BUILD THE GALVO WAVEFORMS (using function in "private" sub-directory)
130138
dataToPlay = generateGalvoWaveforms(imSize,amp,samplesPerPixel,fillFraction,scanPattern);
131139
%We want at least 250 ms of data in the queue, to be really certain don't we hit buffer underflows and the scanning stops
132-
secondsOfDataInQueue = length(dataToPlay)/sampleRate;
140+
secondsOfDataInQueue = length(dataToPlay)/s.Rate;
133141
minDataThreshold = 0.25; %Must have at least this much data in the queue
134142
nFramesToQueue = ceil(minDataThreshold/secondsOfDataInQueue);
135143
dataToPlay = repmat(dataToPlay,nFramesToQueue ,1); %expand queued data accordingly
136144

137-
msOfDataInQueue = round( (length(dataToPlay)/sampleRate)*1000 );
145+
msOfDataInQueue = round( (length(dataToPlay)/s.Rate)*1000 );
138146
fprintf('There is %d ms of data in the output queue ', msOfDataInQueue)
139147
if nFramesToQueue>1
140148
fprintf('(queuing in blocks of %d frames)',nFramesToQueue)
@@ -143,7 +151,7 @@ function scanAndAcquire_Polished(hardwareDeviceID,varargin)
143151

144152
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
145153
% PREPARE TO ACQUIRE
146-
fps = sampleRate/length(dataToPlay);
154+
fps = s.Rate/length(dataToPlay);
147155
fps = fps * nFramesToQueue;
148156
fprintf('Scanning with a frame size of %d by %d at %0.2f frames per second\n',imSize,imSize,fps)
149157

@@ -184,7 +192,8 @@ function scanAndAcquire_Polished(hardwareDeviceID,varargin)
184192
end
185193

186194
%Tweak settings on axes and figure elemenents
187-
set([h(:).imAx], 'XTick',[], 'YTick', [])
195+
set([h(:).imAx], 'XTick',[], 'YTick', [], 'CLim',[0,AI_range]) %note: we store the AI_range here
196+
188197
colormap gray
189198

190199
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -224,7 +233,7 @@ function plotData(~,event)
224233
end
225234

226235
%External function call to function in private directory
227-
plotImageData(downSampled,h,saveFname,scanPattern)
236+
plotImageData(downSampled,h,saveFname,bidiPhase)
228237

229238
end %plotData
230239

0 commit comments

Comments
 (0)