Skip to content

Commit

Permalink
update 20241017
Browse files Browse the repository at this point in the history
  • Loading branch information
RunhuiLi committed Oct 17, 2024
0 parents commit 7dd30b3
Show file tree
Hide file tree
Showing 167 changed files with 5,410 additions and 0 deletions.
35 changes: 35 additions & 0 deletions ##ProcessingPipeline##/@Mcd_Frame/Mcd_Frame.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
classdef Mcd_Frame
%mind control data
properties
FrameNumber = NaN; %internal frame number, not nth recorded frame
TimeElapsed = NaN; %time since start of experiment (in s)
Head = [NaN NaN]; %position in pixels on camera
Tail = [NaN NaN]; %position in pixels on camera
BoundaryA = [1:200]*NaN; %2*N length vector xyxyxy position in pixels on camera
BoundaryB = [1:200]*NaN; %2*N length vector xyxyxy position in pixels on camera
SegmentedCenterline = [1:200]*NaN; %2*N length vector xyxyxy position in pixels on camera
DLPisOn = 0; %bool whether DLP is active
FloodLightIsOn =0; %flood light overrides all other patterns and hits entire fov
IllumInvert =0; %whether pattern is inverted (invert has precedence over floodlight)
IllumFlipLR =0; %flips output left/right with respect to worm's body
IllumRectOrigin =0; %center of the freehand rectangular illumination in wormspace
IllumRectRadius =0; %xy value describing dimension of rectangle
StageVelocity =0; %velocity sent to stage in stage units/second
ProtocolIsOn =0; %bool whether you're using protocol
ProtocolStep =0; %what step within protocol is currently selected
GreenLaser =0; %int 0-100 of relative laser power. -1 means leaser is not being controlled programmatically
BlueLaser =0; %int 0-100 of relative laser power. -1 means leaser is not being controlled programmatically
HeadCurv =0; %curvature of the head
HeadCurvDeriv =0; %derivative of curvature of the head
StagePosition = [NaN NaN];
StageFeedbackTarget = [NaN NaN];
end

methods (Static)
mcdf_arr = yaml2matlab(fname);
mcdf = readOneFrame(fid);
success = seekToFirstFrame(fid);
end

end

292 changes: 292 additions & 0 deletions ##ProcessingPipeline##/@Mcd_Frame/readOneFrame.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,292 @@
function mcdf=readOneFrame(fid)
% ret=readOneFrame(fid)
% This function reads in a frame of data in a YAML file created by
% MindControl. It expects to already be at the line of the first frame (not
% the line with the dash in it) as would be teh cast if seekToFirstFrame()
% had been run previously.
%
% Andrew Leifer
% [email protected]
% 2 November 2010

% Read the line after the dash.. this should be a field
tline = fgets(fid);
mcdf=Mcd_Frame;

sElapsed=[];
msRemElapsed=[];

while ~isEndOfFrame(tline)
if isField(tline)
fname=getField(tline);
switch fname
case 'FrameNumber'
[mcdf.FrameNumber tline]=getVal(fid,tline);
case 'sElapsed'
[sElapsed tline]=getVal(fid,tline);
case 'msRemElapsed'
[msRemElapsed tline]=getVal(fid,tline);
case 'Head'
[mcdf.Head tline]=getxy(fid,tline);
case 'Tail'
[mcdf.Tail tline]=getxy(fid,tline);
case 'BoundaryA'
[mcdf.BoundaryA tline]=getCVseq(fid,tline);
case 'BoundaryB'
[mcdf.BoundaryB tline]=getCVseq(fid,tline);
case 'SegmentedCenterline'
[mcdf.SegmentedCenterline tline]=getCVseq(fid,tline);
case 'DLPIsOn'
[mcdf.DLPisOn tline]=getVal(fid,tline);
case 'FloodLightIsOn'
[mcdf.FloodLightIsOn tline]=getVal(fid,tline);
case 'IllumInvert'
[mcdf.IllumInvert tline]=getVal(fid,tline);
case 'IllumFlipLR'
[mcdf.IllumFlipLR tline]=getVal(fid,tline);
case 'IllumRectOrigin'
[mcdf.IllumRectOrigin tline]=getxy(fid,tline);
case 'IllumRectRadius'
[mcdf.IllumRectRadius tline]=getxy(fid,tline);
case 'StageVelocity'
[mcdf.StageVelocity tline]=getij(fid,tline);
case 'ProtocolIsOn'
[mcdf.ProtocolIsOn tline]=getVal(fid,tline);
case 'ProtocolStep'
[mcdf.ProtocolStep tline]=getVal(fid,tline);
case 'HeadCurv'
[mcdf.HeadCurv tline]=getVal(fid,tline);
case 'HeadCurvDeriv'
[mcdf.HeadCurvDeriv tline]=getVal(fid,tline);
case 'StagePosition'
[mcdf.StagePosition tline]=getij(fid,tline);
case'StageFeedbackTarget'
[mcdf.StageFeedbackTarget tline]=getij(fid,tline);
% case 'LaserPower'
% [mcdf.GreenLaser mcdf.BlueLaser tline]=getLaserPower(fid,tline);
otherwise
%disp(['fname matched nothing: ',fname])
tline=fgets(fid);
end



else
%Advance to the Next Line
tline=fgets(fid);
end


end

mcdf.TimeElapsed=sElapsed+.001*msRemElapsed;
end

function ret=isEndOfFrame(tline)
%This function checks to see if the line in str represents an end of frame
%character. In this case an end of frame is either another `-` or a
%non-charector which would be indicitave of the end of the file
ret=0;
if ~ischar(tline)
ret=1;
else

if regexp(tline,'^[ \t\r\n\v\f]*-[ \t\r\n\v\f]*$')
ret=1;
end
end
end

function ret=isField(str)
%This function checks to see if this is a field in the form of
% `field:`
%
% If no field is present it returns 0
% If a field is present it returns 1
if regexp(str,'^[ \t\r\n\v\f]*[a-z,A-Z]*:[ \t\r\n\v\f]')
ret=1;
else
ret=0;
end

end

function ret=isFieldWithValue(str)
%This function checks to see if this is a field in the form of
% `field: "[349, 345, balh balh`
%
% If no returns 0
% If yes returns 1

if regexp(str,'^[ \t\r\n\v\f]*[a-z,A-Z]*:[ \t\r\n\v\f]*[^ \t\r\n\v\f]+')
ret=1;
else
ret=0;
end

end

function fieldName=getField(str)
q=textscan(str,'%q','Delimiter',':');
fieldName=q{1}{1};
end

function [val tline]=getVal(fid,str)
% Function to parse an integer value
% And increment ot the nextg line
if isFieldWithValue(str)
tmp=textscan(str,'%s','Delimiter',':');
val=str2num(tmp{1}{2});
else
val=NaN;
end
tline=fgets(fid);
end

function [xy tline] = getxy(fid,tline)
% Get the xy values from a field that has two subfields, x & y

%The current line should be a field with no values, only children
if ~isFieldWithValue(tline)
%Advance to the next line
tline=fgets(fid);
fname= getField(tline);
while strcmp(fname,'x') || strcmp(fname,'y')
switch fname
case 'x'
[xy(1) tline]=getVal(fid,tline);
fname= getField(tline);
case 'y'
[xy(2) tline]=getVal(fid, tline);
fname= getField(tline);

end
end



else
%Something was wrong
xy=NaN;
end
end

function [ij tline] = getij(fid,tline)
% Get the ij values from a field that has two subfields, x & y

%The current line should be a field with no values, only children
if ~isFieldWithValue(tline)
%Advance to the next line
tline=fgets(fid);
fname= getField(tline);
while strcmp(fname,'i') || strcmp(fname,'j')
switch fname
case 'i'
[ij(1) tline]=getVal(fid,tline);
fname= getField(tline);
case 'j'
[ij(2) tline]=getVal(fid, tline);
fname= getField(tline);

end
end



else
%Something was wrong
xy=NaN;
end
end

function[Green Blue tline]=getLaserPower(fid,tline)
%Get the blue and green laser powers from a YAML struct
%The current line should be a field with no values, only children
if ~isFieldWithValue(tline)
%Advance to the next line
tline=fgets(fid);
fname= getField(tline);
while strcmp(fname,'Blue') || strcmp(fname,'Green')
switch fname
case 'Blue'
[Blue tline]=getVal(fid,tline);
fname= getField(tline);
case 'Green'
[Green tline]=getVal(fid, tline);
fname= getField(tline);

end
end



else
%Something was wrong
Green=-1;
Blue=-1;
end
end



function [data tline]=getCVseq(fid,tline)
%Parce the CV Sequence and advanced the line feed
data=NaN;
stillInStruct=1;

%Advance to the next line
tline=fgets(fid);


if isField(tline)
%parse fieldname
fname=getField(tline);

%While we are reading fields within the struct.. keep going
while strcmp(fname,'data')||strcmp(fname,'dt')||strcmp(fname,'count')||strcmp(fname,'flags')
%If we hit the data part
if strcmp(fname,'data')
%Read in the first line of the data
data= parseIntDataStr(tline);
%And advance a line
tline=fgets(fid);

%while we haven't bumped into another field
while ~isField(tline)
%read in the additional lines of data
data= [data parseIntDataStr(tline)];
tline=fgets(fid);
end
%Now that we've bumped into the next field, lets see what field
%it is
fname=getField(tline);
%and continue looping

else
%Advance to the next line
tline=fgets(fid);
if isField(tline)
%parse fieldname
fname=getField(tline);
end


end

end

end


end

function vec=parseIntDataStr(str)
%Parses a string containing a bunch of integers delimited in some way
%strs = regexp(str,'[0-9]*','match');
%vec = str2double(strs);
ind = regexp(str,'[0-9]*','start');
vec = zeros(size(ind));
for j = 1:length(ind)
vec(j) = sscanf(str(ind(j):end), '%d');
end
end
42 changes: 42 additions & 0 deletions ##ProcessingPipeline##/@Mcd_Frame/seekToFirstFrame.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
function ret =seekToFirstFrame(fid)
% This function seeks to the the first frame of a YAML data file produced
% by the MindControl software.
%
% Returns 1 if success. 0 if failure.
%
% Andrew Leifer
% [email protected]
% 2 November 2010

disp('Seeking to first frame of YAML file.');
%Find Where the Frames Begin
k=1;
while 1 %unless otherwise
k=k+1;

%Read in a Line
tline = fgets(fid);

%If we are at the end of the file, return an error.
if ~ischar(tline)
ret=0;
disp('A frame was not found');
disp(k);
break
end

%If we Found the line with the frames marker
if regexp(tline,'^[ \t\r\n\v\f]*Frames:[ \t\r\n\v\f]*$')
disp('Found beginning of frames');
tline = fgets(fid);
if regexp(tline,'^[ \t\r\n\v\f]*-[ \t\r\n\v\f]*$')
ret=1;
break;
else
ret=0;
disp('Could not actually find any frames.')
break;
end

end
end
23 changes: 23 additions & 0 deletions ##ProcessingPipeline##/@Mcd_Frame/yaml2matlab.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
function mcdf=yaml2matlab(file)
% This function reads in a yaml file produced by the MindControl Software
% and exports an array of MindControl Data Frames (mcdf's) that is easy to
% manipulate in matlab.
%
% Andrew Leifer
% [email protected]
% 2 November 2010


fid = fopen(file);

Mcd_Frame.seekToFirstFrame(fid);
k=1;
while(~feof(fid))
mcdf(k)=Mcd_Frame.readOneFrame(fid); %#ok<AGROW>
k=k+1;
if ~mod(k,10000)
disp(k);
end
end
fclose(fid);

Loading

0 comments on commit 7dd30b3

Please sign in to comment.