function a_p = plotDataCompare(a_md, title_str, props)
% plotDataCompare - Superpose model and data raw traces.
%
% Usage:
% a_p = plotDataCompare(a_md, title_str, props)
%
% Parameters:
% a_md: A model_data_vcs object.
% title_str: (Optional) Text to appear in the plot title.
% props: A structure with any optional properties.
% quiet: If 1, only use given title_str.
% zoom: Zoom into activation or inactivation parts if 'act' or
% 'inact', resp.
% skipStep: Number of voltage steps to skip at the start for zoom (default=0).
% showSub: also plot subtracted current
% showV: also plot voltage protocol.
% levels: Only plot these current and voltage levels
% colorLevels: Cycle colors every this number.
% axisLimits: Set current traces to these limits unless 'zoom' prop
% is specified.
% iLimits: If specified, override axisLimits y-axis values with these
% only for the data plot (not the subtraction plot).
%
% Returns:
% a_p: A plot_abstract object.
%
% Description:
%
% Example:
% >> a_md = model_data_vcs(model, data_vc)
% >> plotFigure(plotDataCompare(a_md, 'my model'))
%
% See also: model_data_vcs, voltage_clamp, plot_abstract, plotFigure
%
% $Id$
%
% Author: Cengiz Gunay <cgunay@emory.edu>, 2010/10/12
if ~ exist('props', 'var')
props = struct;
end
if ~ exist('title_str', 'var')
title_str = '';
end
skip_step = getFieldDefault(props, 'skipStep', 0);
label_zoom = '';
if isfield(props, 'quiet')
all_title = title_str;
else
all_title = [ a_md.id label_zoom title_str ];
end
% zoom to act/inact portions of data
if isfield(props, 'zoom')
if strcmp(props.zoom, 'act')
axis_limits = [getTimeRelStep(a_md.data_vc, 2 + skip_step, [-1 30])*a_md.data_vc.dt*1e3 NaN NaN];
label_zoom = ' - zoom act';
elseif strcmp(props.zoom, 'inact')
axis_limits = [getTimeRelStep(a_md.data_vc, 3 + skip_step, [-1 30])*a_md.data_vc.dt*1e3 NaN NaN];
label_zoom = ' - zoom inact';
else
error([ 'props.zoom = ''' props.zoom ''' not recognized. Use ''act'' ' ...
'or ''inact''.' ]);
end
elseif isfield(props, 'axisLimits')
props.xTicksPos = 'bottom'; % if fixed axis, do not repeat x ticks
axis_limits = props.axisLimits;
if size(props.axisLimits, 1) > 1
% make an X-stack of several plots with different zooms into specified axisLimits
data_ps = {};
for limit_num = 1:size(props.axisLimits, 1)
% recurse
data_ps{limit_num} = ...
plotDataCompare(a_md, title_str, ...
mergeStructs(rmfield(props, 'axisLimits'), ...
struct('showSub', 1, 'showV', 1, ...
'axisLimits', props.axisLimits(limit_num, :))));
end
a_p = plot_stack(data_ps, [], 'x', all_title, ...
struct('yLabelsPos', 'left', 'yTicksPos', ...
'left', 'noTitle', 1));
return;
end
else
axis_limits = [NaN NaN NaN NaN];
end
color_num_levels = getFieldDefault(props, 'colorLevels', size(a_md.data_vc.v_steps, 2));
line_colors = lines(color_num_levels); %hsv(color_num_levels);
if isfield(props, 'levels')
use_levels = props.levels;
a_md.data_vc = setLevels(a_md.data_vc, use_levels);
a_md.model_vc = setLevels(a_md.model_vc, use_levels);
end
data_props = ...
struct('onlyPlot', 'i', ...
'vStep', skip_step + 2, ...
'axisLimits', ...
[ axis_limits(1:2) ...
getFieldDefault(props, 'iLimits', axis_limits(3:4))], ... % 'noLegends', 1, ...
'ColorOrder', line_colors);
model_props = ...
struct('ColorOrder', line_colors, ...
'vStep', skip_step + 2, ...
'onlyPlot', 'i', 'plotProps', ...
struct('LineWidth', 2));
% if it's only one line for each, put legend labels
if size(a_md.data_vc.data, 2) == 1
data_props = ...
mergeStructs(struct('label', 'data'), data_props);
model_props = ...
mergeStructs(struct('label', 'model'), model_props);
end
plot_props = props;
if isfield(props, 'axisLimits')
plot_props = rmfield(plot_props, 'axisLimits');
end
a_p = ...
plot_superpose({...
plot_abstract(a_md.data_vc, all_title, ...
data_props), ...
plot_abstract(a_md.model_vc, '', ...
model_props)}, {}, '', ...
mergeStructs(plot_props, struct('noCombine', 1, 'noTitle', 1, ...
'noLegends', 1, ...
'fixedSize', [4 3])));
plots = { a_p };
sizes = [ 3 ] ;
if isfield(props, 'showSub') && props.showSub ~= 0
plots = [ plots,
{ set(plot_abstract(a_md.data_vc - a_md.model_vc, '', ...
struct('onlyPlot', 'i', 'ColorOrder', line_colors, ...
'axisLimits', axis_limits, ...
'noLegends', 1, ...
'plotProps', struct('LineWidth', 1))), ...
'axis_labels', {'voltage [mV]', 'I_{error} [nA]'})...
} ];
sizes = [ sizes, 1];
end
if isfield(props, 'showVars') && props.showVars ~= 0
m = a_md.model_vc.props.intOuts.m;
h = a_md.model_vc.props.intOuts.h;
time = 1e3*a_md.model_vc.dt*(0:(size(m, 1) - 1));
plots = [ plots,
{ set(plot_superpose({...
plot_abstract({time, m}, {}, '', {'m'}, 'plot', ...
struct('ColorOrder', line_colors, ...
'axisLimits', axis_limits, ...
'noLegends', 1, ...
'plotProps', struct('LineWidth', 1))), ...
plot_abstract({time, h}, {}, '', {'h'}, 'plot', ...
struct('ColorOrder', line_colors, ...
'axisLimits', axis_limits, ...
'noLegends', 1, ...
'plotProps', struct('LineWidth', 1)))}, {}, '', ...
mergeStructs(plot_props, struct('noTitle', 1))), ...
'axis_labels', {'time [ms]', 'gating'})...
} ];
sizes = [ sizes, 1];
end
if isfield(props, 'showV') && props.showV ~= 0
plots = [ plots,
{ plot_superpose({...
plot_abstract(a_md.data_vc, '', ...
struct('onlyPlot', 'v', 'ColorOrder', line_colors, ...
'axisLimits', axis_limits, ...
'noLegends', 1, ...
'plotProps', struct('LineWidth', 1))), ...
plot_abstract(a_md.model_vc, '', ...
struct('onlyPlot', 'v', 'ColorOrder', line_colors, ...
'axisLimits', axis_limits, ...
'noLegends', 1, ...
'plotProps', struct('LineWidth', 2)))}, {}, '', ...
mergeStructs(plot_props, struct('noCombine', 1, 'noTitle', 1))) }];
sizes = [ sizes, 1 ];
end
a_p = ...
plot_stack(plots, ...
[], 'y', all_title, ...
mergeStructs(props, ...
struct('titlesPos', 'none', 'xLabelsPos', 'bottom', ...
'fixedSize', [4 sum(sizes)], 'noTitle', 1, ...
'relativeSizes', sizes)));
end % func