/ concept-collection / seqlab
Sign in
concept-collection / seqlab
seqlab / src / engine / pulseq / +mr / opts.m
131 lines · 5.0 KBCodeBlameHistory
78d04f1seqlab: write and view pulseq MRI sequences in the browserJeremy Magland 1function out=opts(varargin)
2%OPTS Set gradient limits and other system properties of the MR system.
3% g=OPTS() Return the default amplitude and slew limits.
4%
5% g=OPTS('maxGrad',30,'gradUnit','mT/m') Set the maximum gradient to
6% 30mT/m.
7
8persistent defaultUserOpts
9persistent defaultStandardOpts
10if isempty(defaultStandardOpts)
11 defaultStandardOpts=struct(...
12 'maxGrad',mr.convert(40,'mT/m'),... % Default: 40 mT/m
13 'maxSlew',mr.convert(170,'T/m/s'),... % Default: 170 mT/m/ms
14 'maxB1',mr.convert(20,'uT'),... % Default: 20 uT
15 'maxFreqOffset',250e3,... % Default: +-250 kHz -- maximum frequency offset for ADC and RF; some systems may have it higher, but they are probably rare (e.g. Siemens Terra seems to accept 400kHz)
16 'riseTime',[],...
17 'rfDeadTime',0,...
18 'rfRingdownTime',0,...
19 'adcDeadTime',0,...
20 'adcRasterTime',100e-9,...
21 'rfRasterTime',1e-6,...
22 'gradRasterTime',10e-6,...
23 'blockDurationRaster',10e-6,...
24 'adcSamplesLimit',0,... % 0 means no limit
25 'rfSamplesLimit',0,... % 0 means no limit
26 'adcSamplesDivisor',4,... % the number of which the adc.numSamples should be integer multiple
27 'flag_trid', true,... % default: true; false -> can be used to ignore seq.addTRID() statements
28 'gamma',42576000,...
29 'B0',1.5...
30 );
31end
33if ~isempty(defaultUserOpts)
34 defaultOpts=defaultUserOpts;
35else
36 defaultOpts=defaultStandardOpts;
37end
39if isempty(varargin) % accelerate default constructor calls
40 out=defaultOpts;
41 return
42end
44persistent parser
45validB1Units={'Hz','T','mT','uT'}; % todo: gauss?
46validGradUnits={'Hz/m','mT/m','rad/ms/mm'};
47validSlewUnits={'Hz/m/s','mT/m/ms','T/m/s','rad/ms/mm/ms'};
48if isempty(parser)
49 parser = inputParser;
50 parser.FunctionName = 'opts';
51 parser.addParamValue('gradUnit',validGradUnits{1},...
52 @(x) any(validatestring(x,validGradUnits)));
53 parser.addParamValue('slewUnit',validSlewUnits{1},...
54 @(x) any(validatestring(x,validSlewUnits)));
55 parser.addParamValue('b1Unit',validB1Units{1},...
56 @(x) any(validatestring(x,validB1Units)));
57 parser.addParamValue('maxGrad',[],@isnumeric);
58 parser.addParamValue('maxSlew',[],@isnumeric);
59 parser.addParamValue('maxB1',[],@isnumeric);
60 parser.addParamValue('riseTime',[],@isnumeric);
61 parser.addParamValue('maxFreqOffset',defaultOpts.maxFreqOffset,@isnumeric);
62 parser.addParamValue('rfDeadTime',defaultOpts.rfDeadTime,@isnumeric);
63 parser.addParamValue('rfRingdownTime',defaultOpts.rfRingdownTime,@isnumeric);
64 parser.addParamValue('adcDeadTime',defaultOpts.adcDeadTime,@isnumeric);
65 parser.addParamValue('adcRasterTime',defaultOpts.adcRasterTime,@isnumeric);
66 parser.addParamValue('rfRasterTime',defaultOpts.rfRasterTime,@isnumeric);
67 parser.addParamValue('gradRasterTime',defaultOpts.gradRasterTime,@isnumeric);
68 parser.addParamValue('blockDurationRaster',defaultOpts.blockDurationRaster,@isnumeric);
69 parser.addParamValue('adcSamplesLimit',defaultOpts.adcSamplesLimit,@isnumeric);
70 parser.addParamValue('rfSamplesLimit',defaultOpts.rfSamplesLimit,@isnumeric);
71 parser.addParamValue('adcSamplesDivisor',defaultOpts.adcSamplesDivisor,@isnumeric);
72 parser.addParamValue('flag_trid',defaultOpts.flag_trid,@(x) islogical(x) || isnumeric(x));
73 parser.addParamValue('gamma',defaultOpts.gamma,@isnumeric); % Hz/T
74 parser.addParamValue('B0',defaultOpts.B0,@isnumeric); % T
75 parser.addParamValue('setAsDefault',false,@islogical);
76 parser.addParamValue('resetDefault',false,@islogical);
77end
78parse(parser,varargin{:});
79opt = parser.Results;
81if opt.resetDefault
82 defaultUserOpts=[];
83 parser=[];
84 return;
85end
87if isempty(opt.maxB1)
88 maxB1 = defaultOpts.maxB1;
89else
90 maxB1 = mr.convert(opt.maxB1,opt.b1Unit,'Hz','gamma',opt.gamma);
91end
92if isempty(opt.maxGrad)
93 maxGrad = defaultOpts.maxGrad;
94else
95 maxGrad = mr.convert(opt.maxGrad,opt.gradUnit,'Hz/m','gamma',opt.gamma);
96end
97if isempty(opt.maxSlew)
98 maxSlew=defaultOpts.maxSlew;
99else
100 maxSlew = mr.convert(opt.maxSlew,opt.slewUnit,'Hz/m/s','gamma',opt.gamma);
101end
102if ~isempty(opt.riseTime)
103 %maxSlew=[];
104 maxSlew=maxGrad/opt.riseTime;
105end
107out.maxGrad = maxGrad;
108out.maxSlew = maxSlew;
109out.maxB1 = maxB1;
110out.maxFreqOffset = opt.maxFreqOffset;
111out.riseTime = opt.riseTime;
112out.rfDeadTime = opt.rfDeadTime;
113out.rfRingdownTime = opt.rfRingdownTime;
114out.adcDeadTime = opt.adcDeadTime;
115out.adcRasterTime = opt.adcRasterTime;
116out.rfRasterTime = opt.rfRasterTime;
117out.gradRasterTime = opt.gradRasterTime;
118out.blockDurationRaster = opt.blockDurationRaster;
119out.adcSamplesLimit = opt.adcSamplesLimit;
120out.rfSamplesLimit = opt.rfSamplesLimit;
121out.adcSamplesDivisor = opt.adcSamplesDivisor;
122out.flag_trid = logical(opt.flag_trid);
123out.gamma=opt.gamma;
124out.B0=opt.B0;
126if opt.setAsDefault
127 defaultUserOpts=out;
128 parser=[];
129end
131end
moveopenescclose