Skip to content

Commit

Permalink
Running to example sendSamples
Browse files Browse the repository at this point in the history
  • Loading branch information
raacampbell committed Dec 13, 2022
1 parent ad5cbd5 commit d267d90
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 47 deletions.
52 changes: 35 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,25 +89,43 @@ Closing the figure will also disconnect from the camera, as will `delete(D)`
### Start beam pointer and calibrate

```
laserObject = beamPointer;
P = zapit.pointer;
% find transformation of pixel coords into voltage for scan mirrors
pointLog = laserObject.logPoints;
[tform, laserObject] = laserObject.runAffineTransform(pointLog);
P.logPoints;
```
You can now click on the image and the beam should go to that location.


### Calibrate to mouse skull
Now you can tell the system where is Bregma and another reference location
```
P.getAreaCoordinates
```

### Generate the parameters for switching the beam
Here we are switching at 40 Hz with a laser amplitude of 0.36
```
P.makeChanSamples(40, 0.36);
```

### Set up NI task for the stimulation
```
P.createNewTask %% TODO - should run this in sendSamples
```


### Let's run it
For one brain area
```
newTrial.area = 1; % first brain area on the list
newTrial.LaserOn = 1;
newTrial.powerOption = 1; % if 1 send 2 mW, if 2 send 4 mW (mean)
```

### Legacy (?) Example
```
bp = beamPointer;
OUT = bp.logPoints(7) %scales laser to location in image##
bp.cam.src.Gain =1
load('C:\Maja\pulsepal_beta\fsm-behaviour-maja\scanner\areas1.mat')
bp.getAreaCoordinates(template)
bp.makeChanSamples(40, 0.36);
bp.createNewTask
bp.cam.src.Gain = 1;
P.cam.src.Gain = 1;
%%
x = randi(6, 300, 1);
Expand All @@ -120,17 +138,17 @@ for ii = 1:300
{'ii' 'x' 't' }
[ii x(ii) t(ii) ]
%
bp.sendSamples(x(ii), 1);
P.sendSamples(x(ii), 1);
pause(t(ii));
bp.hTask.stop;
bp.sendSamples(x(ii), 0);
P.hTask.stop;
P.sendSamples(x(ii), 0);
pause(t(ii));
bp.hTask.stop;
P.hTask.stop;
end
%%
% get order of inactivated areas
save('runningtest4', 'x', 't', 'bp');
save('runningtest4', 'x', 't', 'P');
```

Expand Down
2 changes: 1 addition & 1 deletion code/+zapit/@config/config.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function loadConfig(obj,fname)
data = zapit.yaml.ReadYaml(fname);

obj.powerOption = data.powerOption;
obj.refPoints = data.refPoints;
obj.refPoints = cell2mat(data.refPoints);


% template is 2 by n (by n?) array
Expand Down
44 changes: 25 additions & 19 deletions code/+zapit/@pointer/getAreaCoordinates.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@
% volts

% change illumination to get a clearer image of beam position
obj.cam.src.Gain = 25;

obj.cam.src.Gain = 2;

% Clear any old coords
delete(obj.hAreaCoords)
obj.hAreaCoords = [];

delete(obj.hRefCoords)
obj.hRefCoords = [];

% record points in the screen
refPoints = obj.config.refPoints; % coordinate references on the mouse skull (bregma and 0,-2 marked with pen)
refPoints = obj.config.refPoints; % coordinate references on the mouse skull (bregma and 0,-2 marked with pen)
template = obj.config.template;
hold(obj.hImAx, 'on');
% plot(obj.hImAx, refPoints(:,1), refPoints(:,2));
realPoints = recordPoints(obj.hImAx, obj.hFig); % output columns are x and y coords

Expand All @@ -29,23 +35,18 @@
coordsLibrary = [xVolt' yVolt'];
coordsLibrary(:,:,2) = [xVolt2' yVolt2'];

coordsLibrary
obj.coordsLibrary = coordsLibrary;
obj.newpoint = newpoint;


hold(obj.hImAx, 'on');
plot(obj.hImAx, newpoint(1, :, 1), newpoint(2, :, 1), 'o'); % left hemisphere coords
plot(obj.hImAx, newpoint(1, :, 2), newpoint(2, :, 2), 'o'); % right hemisphere coords

% move laser into each position as a check
for xx = 1:length(newpoint)
for yy = 1:2
obj.hTask.writeAnalogData([obj.coordsLibrary(xx, 1, yy), obj.coordsLibrary(xx, 2, yy)]);
pause(1)
end
end

obj.hAreaCoords(1) = plot(obj.hImAx, newpoint(1,:,1), newpoint(2,:,1), 'o'); % left hemisphere coords
obj.hAreaCoords(2) = plot(obj.hImAx, newpoint(1,:,2), newpoint(2,:,2), 'o'); % right hemisphere coords
hold(obj.hImAx, 'off');


% Move points through all locations to check visually that all is good
obj.testCoordsLibray;


%% functions
Expand All @@ -65,7 +66,8 @@
figure(hImFig)
waitforbuttonpress;
end
figureText = join(['bregma recorded, click ', string(refPoints(:,2)')]);

figureText = sprintf('bregma recorded, click %d %d ', refPoints(:,2));
title(hImAx,figureText);
figure(hImFig)
waitforbuttonpress;
Expand All @@ -76,7 +78,11 @@
end

title(hImAx, 'both points recorded');
plot(hImAx, points(:,1), points(:,2));

hold(obj.hImAx, 'on');
obj.hRefCoords = plot(hImAx, points(:,1), points(:,2));
hold(obj.hImAx, 'off');

end

function [newpoint,rotMat] = coordsRotation(template, refPoints, points)
Expand Down Expand Up @@ -106,7 +112,7 @@

function [newpoint, opaqueArea] = checkOpaqueArea(obj, newpoint)
% TODO -- refactor to model/view
opaqueArea = input('using an additional opaque area as control? 1 or 0');
opaqueArea = input('using an additional opaque area as control?\n[1 or 0] ');
if opaqueArea
figure(obj.hFig)
title(obj.hImAx, 'find opaque area 1')
Expand Down
13 changes: 11 additions & 2 deletions code/+zapit/@pointer/logPoints.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function OUT = logPoints(obj, nPoints, doPointGrid)
function varargout = logPoints(obj, nPoints, doPointGrid)
% Log precision of beam pointing: conduct an affine transform to calibrate camera and beam
%
% Purpose
Expand All @@ -14,7 +14,9 @@
% output: target and actual pixel coordinates

% lower camera illumination for precision
obj.cam.src.Gain = 1;

obj.cam.src.Gain = 1; % TODO - hard-coded
obj.cam.exposure = 3000; % TODO - hard-coded

if nargin<2
nPoints = [];
Expand Down Expand Up @@ -51,14 +53,17 @@
% change pixel coords into voltage %TODO -- R and C correct?
[rVolts(:,1), rVolts(:,2)] = obj.pixelToVolt(R,C);

fprintf('Running calibration')
for ii=1:length(R)
% feed volts into scan mirrors, wait for precise image
% without smudges and take position in pixels
obj.hTask.writeAnalogData([rVolts(ii,:), 3.3]);
pause(0.125)
v(ii)=obj.getLaserPosAccuracy([R(ii), C(ii)]);
drawnow
fprintf('.')
end
fprintf('\n')

else
% TODO -- DOES NOT WORK RIGHT NOW FOR SOME REASON
Expand Down Expand Up @@ -101,4 +106,8 @@
obj.hTask.writeAnalogData([0 0 0]); % Zero beam and turn off laser

% TODO: now demonstrate that it worked

if nargout>0
varargout{1} = OUT;
end
end
45 changes: 37 additions & 8 deletions code/+zapit/@pointer/pointer.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
newpoint
topUpCall
rampDown % Not used
chanSamples
chanSamples %Structure describing waveforms to send the scanners for each brain area
topCall = 1;
freqLaser
numSamplesPerChannel
Expand All @@ -46,6 +46,9 @@
hImLive
hLastPoint % plot handle with location of the last clicked point

hAreaCoords % locations where the beam will be sent. see getAreaCoords
hRefCoords % The two reference coords

axRange
imSize % Size of the displayed image

Expand All @@ -61,8 +64,13 @@


methods
function obj = pointer
function obj = pointer(fname)
% Constructor

if nargin < 1
fname = [];
end

disp('STARTING BEAMPOINTER')
obj.cam = zapit.camera(2); % TODO - Hard-coded selection of camera ID

Expand All @@ -87,10 +95,13 @@

obj.zeroScanners


% load configuration files
[fname,fpath] = uigetfile('*.yaml','Pick a config file');
pathToConfig = fullfile(fpath,fname);
if isempty(fname)
[fname,fpath] = uigetfile('*.yaml','Pick a config file');
pathToConfig = fullfile(fpath,fname);
else
pathToConfig = fname;
end
obj.config = zapit.config(pathToConfig);
end

Expand Down Expand Up @@ -145,6 +156,7 @@ function sendSamples(obj, new_trial)
% powerOption - if 1 send 2 mW, if 2 send 4 mW (mean)
% output: nothing. The function just sends correct samples to
% the pointer

CoordNum = new_trial.area;
LaserOn = new_trial.LaserOn;
trialPower = new_trial.powerOption;
Expand All @@ -155,7 +167,7 @@ function sendSamples(obj, new_trial)
% right properties. hTask is an object that 'rests' on the NI
% board and gives it information to play back once command start
% arrives. It contains a clock and sampled voltages.
createNewTask(obj, taskName);
obj.createNewTask(taskName);
end

% update coordinate parameters/channel samples
Expand All @@ -167,15 +179,19 @@ function sendSamples(obj, new_trial)

% write voltage samples onto the task
obj.hTask.writeAnalogData(voltChannel);

% start the execution of the new task
obj.hTask.start;

% TODO the task is continuing to run, which is wrong. It should play out the finite
% samples then it stops.
end


function createNewTask(obj, taskName)

devName = 'Dev2';

% channel 0 = x Axis
% channel 1 = y Axis
% channel 2 = analog laser
Expand Down Expand Up @@ -262,7 +278,20 @@ function topUpBuffer(obj)
obj.hTask.writeAnalogData(obj.voltChannel);
end
end


function testCoordsLibray(obj)
% move laser into each position as a check
for xx = 1:length(obj.newpoint)
for yy = 1:2
fprintf('Testing coordinate %0.2f %0.2f\n', ...
obj.coordsLibrary(xx, 1, yy), ...
obj.coordsLibrary(xx, 2, yy))
obj.hTask.writeAnalogData([obj.coordsLibrary(xx, 1, yy), obj.coordsLibrary(xx, 2, yy),2]);
pause(0.25)
end
end
end


function pointBeamToLocationInImage(obj,~,~)
% This callback function obtains the mouse position in the
Expand Down

0 comments on commit d267d90

Please sign in to comment.