1function varargout=addRamps(k,varargin)
2%addRamps Add segments to the trajectory to ramp to and from the given trajectory.
3% kout=addRamps(k) Add a segment to k so kout travels from 0 to k(1) and
4% a segment so kout goes from k(end) back to 0 without violating the
5% gradient and slew constraints.
6%
7% [kx,ky,...]=addRamps({kx,ky,...}) Add segments of the same length
8% for each trajectory in the cell array.
9%
10% [...,rf]=addRamps(...,'rf',rf) Add a segment of zeros over the ramp
11% times to an RF shape.
12%
13% See also Sequence.makeArbitraryGrad
15persistent parser
16if isempty(parser)
17 parser = mr.aux.InputParserCompat;
18 parser.FunctionName = 'addRamps';
19 parser.addRequired('k',@(x)(isnumeric(x)||iscell(x)));
20 parser.addOptional('system',[],@isstruct);
21 parser.addParamValue('rf',[],@isnumeric);
22 parser.addParamValue('maxGrad',0,@isnumeric);
23 parser.addParamValue('maxSlew',0,@isnumeric);
24 parser.addParamValue('gradOversampling',false,@islogical);
26end
27parse(parser,k,varargin{:});
28opt = parser.Results;
30if isempty(opt.system)
31 system=mr.opts();
32else
33 system=opt.system;
34end
36if opt.maxGrad>0
37 system.maxGrad=opt.maxGrad;
38end
39if opt.maxSlew>0
40 system.maxSlew=opt.maxSlew;
41end
43if iscell(opt.k)
44 k=cell2mat(opt.k(:));
45else
46 k=opt.k;
47end
49nChannels=size(k,1);
50k=[k; zeros(3-nChannels,size(k,2))]; % Pad out with zeros if needed
52[kUp, ok1] = mr.calcRamp(zeros(3,2),k(:,1:2),system,'gradOversampling',opt.gradOversampling);
53[kDown, ok2] = mr.calcRamp(k(:,end-1:end),zeros(3,2),system,'gradOversampling',opt.gradOversampling);
54assert(ok1 & ok2,'Failed to calculate gradient ramps');
56kUp = [zeros(3,2), kUp]; % Add start and end points to ramps
57kDown = [kDown, zeros(3,1)];
59k = [kUp, k, kDown]; % Add ramps to trajectory
61if isnumeric(opt.k)
62 varargout{1} = k(1:nChannels,:);
63else
64 for i=1:nChannels
65 varargout{i}=k(i,:);
66 end
67end
68if ~isempty(opt.rf)
69 varargout{end+1}=[zeros(1,size(kUp,2)*10), opt.rf, zeros(1,size(kDown,2)*10)];
70end
73end