|
a |
|
b/Analysis/jPCA_ForDistribution/phaseMovie.m |
|
|
1 |
% For making rosette movies for the paper |
|
|
2 |
% useage: |
|
|
3 |
% |
|
|
4 |
% phaseMovie(Projection, Summary); Easiest usage. Just plot in matlab. Use default params. |
|
|
5 |
% phaseMovie(Projection, Summary, movieParams); Can override one or more parameters |
|
|
6 |
% MV = phaseMovie(Projection, Summary, movieParams); if you need to save a movie |
|
|
7 |
% |
|
|
8 |
% To save the movie use: movie2avi(MV, 'movieName', 'FPS', 12, 'compression', 'none'); |
|
|
9 |
% |
|
|
10 |
% 'movieParams' can contain the following fields: |
|
|
11 |
% .plane2plot Default is 1. Set to 2 to see the second plane (and so on) |
|
|
12 |
% .rankType Default is 'eig': the first plane is that associated with the largest eigenvalue. |
|
|
13 |
% Can also be 'varCapt' |
|
|
14 |
% .times Default is Projection(1).times. Note that you can specify a subset of those |
|
|
15 |
% times or a superset. If the latter, only those times that lie within |
|
|
16 |
% 'allTimes' will be used. |
|
|
17 |
% .conds2plot Default is 'all'. Can also be a scalar (to plot a single cond), or a vector of |
|
|
18 |
% conds (e.g., [1 5 12 27]; |
|
|
19 |
% .substRawPCs Substitute raw PCs. |
|
|
20 |
% .pixelsToGet You may wish to customize these, esp. if the defaults don't work well on your |
|
|
21 |
% screen. Co-ordinates are left then bottom, then width then height. |
|
|
22 |
% See getframe for more info. |
|
|
23 |
% .usePads Default is 0. If '1', stationary pads will be added to start and end of |
|
|
24 |
% movie. This can be useful in some media players (though not keynote). |
|
|
25 |
% .arrowGain Controls how much the arrow grows with speed. Default is 25; |
|
|
26 |
% .tail If specified and not empty, a tail of this length (in ms) will be produced, instead of the whole trajectory. |
|
|
27 |
|
|
|
28 |
|
|
|
29 |
function MV = phaseMovie(Projection, Summary, movieParams) |
|
|
30 |
|
|
|
31 |
|
|
|
32 |
%% Set defaults and override if fields are set in 'movieParams' |
|
|
33 |
|
|
|
34 |
|
|
|
35 |
% PLANE |
|
|
36 |
% Plot the first plane (eigenvalue-wise) unless asked to do otherwise |
|
|
37 |
frameParams.planes2plot = 1; |
|
|
38 |
if exist('movieParams', 'var') && isfield(movieParams,'plane2plot') |
|
|
39 |
frameParams.planes2plot = movieParams.plane2plot(1); % do what we are told, but we can only plot one plane |
|
|
40 |
end |
|
|
41 |
frameParams.rankType = 'eig'; % can also be 'varCapt' |
|
|
42 |
if exist('movieParams', 'var') && isfield(movieParams,'rankType') |
|
|
43 |
frameParams.rankType = movieParams.rankType; |
|
|
44 |
end |
|
|
45 |
|
|
|
46 |
|
|
|
47 |
% TIMES |
|
|
48 |
times2plot = Projection(1).times; |
|
|
49 |
if exist('movieParams', 'var') && isfield(movieParams,'times') |
|
|
50 |
times2plot = movieParams.times; |
|
|
51 |
times2plot = times2plot(ismember(times2plot, Projection(1).allTimes)); % can only plot what we have access to |
|
|
52 |
end |
|
|
53 |
|
|
|
54 |
% CONDS |
|
|
55 |
frameParams.conds2plot = 'all'; |
|
|
56 |
if exist('movieParams', 'var') && isfield(movieParams,'conds2plot') |
|
|
57 |
frameParams.conds2plot = movieParams.conds2plot; |
|
|
58 |
end |
|
|
59 |
|
|
|
60 |
% jPCs or raw PCs |
|
|
61 |
frameParams.substRawPCs = false; |
|
|
62 |
if exist('movieParams', 'var') && isfield(movieParams,'substRawPCs') |
|
|
63 |
frameParams.substRawPCs = movieParams.substRawPCs; |
|
|
64 |
end |
|
|
65 |
|
|
|
66 |
% PIXELS |
|
|
67 |
pixelsToGet = [70 -90 600 590]; |
|
|
68 |
if exist('movieParams', 'var') && isfield(movieParams,'pixelsToGet') |
|
|
69 |
pixelsToGet = movieParams.pixelsToGet; |
|
|
70 |
end |
|
|
71 |
|
|
|
72 |
% Stationary Padding |
|
|
73 |
% Default is we do not add any stationary padding to start or end. But we will if asked |
|
|
74 |
usePads = false; |
|
|
75 |
if exist('movieParams', 'var') && isfield(movieParams,'usePads') |
|
|
76 |
usePads = movieParams.usePads; |
|
|
77 |
end |
|
|
78 |
% These are used only if the above flag is true |
|
|
79 |
stationaryPadStart = 18; % extra frames at the beginning of stationary image. |
|
|
80 |
stationaryPadEnd = 24; % extra frames at the end of stationary image. |
|
|
81 |
|
|
|
82 |
% Arrow size changes with speed |
|
|
83 |
frameParams.arrowGain = 25; % controls how the arrow grows with speed |
|
|
84 |
if exist('movieParams', 'var') && isfield(movieParams,'arrowGain') |
|
|
85 |
frameParams.arrowGain = movieParams.arrowGain; |
|
|
86 |
end |
|
|
87 |
|
|
|
88 |
% Tail |
|
|
89 |
tail = []; |
|
|
90 |
if exist('movieParams', 'var') && isfield(movieParams,'tail') |
|
|
91 |
tail = movieParams.tail; |
|
|
92 |
end |
|
|
93 |
|
|
|
94 |
|
|
|
95 |
|
|
|
96 |
% These plotting parameters are currently hard coded (can't be changed by movieParams) |
|
|
97 |
% If needed, one can of course |
|
|
98 |
frameParams.arrowSize = 3.3; % will likely grow |
|
|
99 |
frameParams.planMarkerSize = 6.5; |
|
|
100 |
frameParams.lineWidth = 0.5; |
|
|
101 |
frameParams.useAxes = 0; |
|
|
102 |
frameParams.useLabel = 0; |
|
|
103 |
frameParams.plotPlanEllipse = 0; |
|
|
104 |
frameParams.reusePlot = 0; % will change to one after first frame |
|
|
105 |
|
|
|
106 |
if ~isempty(tail) |
|
|
107 |
frameParams.planMarkerSize = 0; % not plan marker if we are using a non-infinite tail |
|
|
108 |
end |
|
|
109 |
|
|
|
110 |
|
|
|
111 |
%% Done handling parameters and defaults |
|
|
112 |
% Print some things out to confirm to the user the choices being made |
|
|
113 |
fprintf('using plane %d (ordered by %s)\n', frameParams.planes2plot, frameParams.rankType); |
|
|
114 |
fprintf('movie runs from time %d to %d\n', times2plot([1,end])); |
|
|
115 |
fprintf('pixels: [%d %d %d %d]\n', pixelsToGet); |
|
|
116 |
|
|
|
117 |
|
|
|
118 |
%% Now start plotting stuff |
|
|
119 |
|
|
|
120 |
fi = 1; % frame index |
|
|
121 |
|
|
|
122 |
%% start pad |
|
|
123 |
if nargout > 0 && usePads == 1 |
|
|
124 |
% pad at start if we are making the movie to export, rather than just view in matlab |
|
|
125 |
|
|
|
126 |
for i = 1:stationaryPadStart |
|
|
127 |
frameParams.times = times2plot(1):times2plot(2); |
|
|
128 |
|
|
|
129 |
phaseSpace(Projection, Summary, frameParams); |
|
|
130 |
drawnow; |
|
|
131 |
frameParams.reusePlot = 1; % after the first frame, always reuse |
|
|
132 |
|
|
|
133 |
if nargout > 0 |
|
|
134 |
MV(fi) = getframe(gca, pixelsToGet); |
|
|
135 |
fi=fi+1; |
|
|
136 |
end |
|
|
137 |
end |
|
|
138 |
end |
|
|
139 |
|
|
|
140 |
%% ** ACTUAL MOVIE ** |
|
|
141 |
for ti = 2:length(times2plot) |
|
|
142 |
frameParams.times = times2plot(1):times2plot(ti); % only times that match one of these will be used |
|
|
143 |
if ~isempty(tail) && range(frameParams.times) > tail |
|
|
144 |
frameParams.times = frameParams.times(frameParams.times > frameParams.times(end)-tail); |
|
|
145 |
end |
|
|
146 |
|
|
|
147 |
phaseSpace(Projection, Summary, frameParams); |
|
|
148 |
drawnow; |
|
|
149 |
frameParams.reusePlot = 1; % after the first frame, always reuse |
|
|
150 |
|
|
|
151 |
if nargout > 0 |
|
|
152 |
MV(fi) = getframe(gca, pixelsToGet); |
|
|
153 |
fi=fi+1; |
|
|
154 |
end |
|
|
155 |
end |
|
|
156 |
|
|
|
157 |
%% end pad |
|
|
158 |
if nargout > 0 && usePads == 1 |
|
|
159 |
% pad at start if we are making the movie to export, rather than just view in matlab |
|
|
160 |
for i = 1:stationaryPadEnd |
|
|
161 |
frameParams.times = times2plot(1):times2plot(end); |
|
|
162 |
|
|
|
163 |
phaseSpace(Projection, Summary, frameParams); |
|
|
164 |
drawnow; |
|
|
165 |
frameParams.reusePlot = 1; % after the first frame, always reuse |
|
|
166 |
|
|
|
167 |
if nargout > 0 |
|
|
168 |
MV(fi) = getframe(gca, pixelsToGet); |
|
|
169 |
fi=fi+1; |
|
|
170 |
end |
|
|
171 |
end |
|
|
172 |
end |
|
|
173 |
|
|
|
174 |
|
|
|
175 |
if ~exist('MV', 'var') % if we were not asked to make the movie structure |
|
|
176 |
MV = []; |
|
|
177 |
end |
|
|
178 |
|
|
|
179 |
|
|
|
180 |
|