-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
KomaMRIFiles: Include .seq produced by pypulseq or pulseq #318
Comments
It could possibly be good to leverage the tests for related KomaMRI or julia functions (read or generate seq or other files) from pulseq or pypulseq directly by sending KomaMRI input or output visa versa to those tests. |
This was done in https://github.com/JuliaHealth/KomaMRI.jl/blob/master/KomaMRIFiles/test/runtests.jl#L53-L82 To include more tests, we just need to include Pulseq files in To generate the corresponding %% Just read a .seq and write the .mat
clc
cd('/home/ccp/Documents/KomaMRI.jl/KomaMRIFiles/test/test_files/pulseq_read_comparison/')
sys = mr.opts(); % Default system
seq = mr.Sequence(sys); % Default sequence
files = dir('*.seq');
for i = 1:length(files)
seq.read(files(i).name);
seq_name = split(files(i).name, '.');
seq.setDefinition('FileName', seq_name{1});
seq.plot() %<---- Modified version that saves the generated samples
end and the modified diff --git a/matlab/+mr/@Sequence/Sequence.m b/matlab/+mr/@Sequence/Sequence.m
index acf3d18..e7b45b4 100644
--- a/matlab/+mr/@Sequence/Sequence.m
+++ b/matlab/+mr/@Sequence/Sequence.m
@@ -1255,6 +1255,17 @@ classdef Sequence < handle
end
end
%for iB=1:size(obj.blockEvents,1)
+ % Generating struct to save event samples to then compare them with Koma
+ koma_gamma = 42577468.8;
+ sequence = cell(1, length(obj.blockEvents));
+ for i = 1:length(obj.blockEvents)
+ sequence{i} = struct('rf', struct('t', [], 'A', []),...
+ 'df', struct('t', [], 'A', []),...
+ 'gx', struct('t', [], 'A', []),...
+ 'gy', struct('t', [], 'A', []),...
+ 'gz', struct('t', [], 'A', []),...
+ 'adc',struct('t', [], 'A', []));
+ end
for iB=1:length(obj.blockEvents)
block = obj.getBlock(iB);
isValid = t0+obj.blockDurations(iB)>timeRange(1) && t0<=timeRange(2);
@@ -1286,22 +1297,28 @@ classdef Sequence < handle
label_legend_2plot=[];
end
end
+ % Saving the ADC points to compare with Koma
+ sequence{iB}.adc.t = tFactor * (t0 + t);
+ sequence{iB}.adc.A = ones(size(t));
end
if ~isempty(block.rf)
rf=block.rf;
[tc,ic]=mr.calcRfCenter(rf);
sc=rf.signal(ic);
- if max(abs(diff(rf.t)-rf.t(2)+rf.t(1)))<1e-9 && length(rf.t)>100
- % homogeneous sampling and long pulses -- use lower time resolution for better display and performance
- dt=rf.t(2)-rf.t(1);
- st=round(obj.sys.gradRasterTime/dt);
- t=rf.t(1:st:end);
- s=rf.signal(1:st:end);
- else
+ %if max(abs(diff(rf.t)-rf.t(2)+rf.t(1)))<1e-9 && length(rf.t)>100
+ % % homogeneous sampling and long pulses -- use lower time resolution for better display and performance
+ % dt=rf.t(2)-rf.t(1);
+ % st=round(obj.sys.gradRasterTime/dt);
+ % t=rf.t(1:st:end);
+ % s=rf.signal(1:st:end);
+ %else
t=rf.t;
s=rf.signal;
- end
+ %end
sreal=max(abs(imag(s)))/max(abs(real(s)))<1e-6; %all(isreal(s));
+ % Saving raw waveform to compare with Koma
+ s_saved = [0; s; 0];
+ t_saved = [t(1); t; t(end)];
if abs(s(1))~=0 % fix strangely looking phase / amplitude in the beginning
s=[0; s];
t=[t(1); t];
@@ -1318,6 +1335,12 @@ classdef Sequence < handle
plot(tFactor*(t0+t+rf.delay), abs(s),'Parent',ax(2));
plot(tFactor*(t0+t+rf.delay), angle(s*exp(1i*rf.phaseOffset).*exp(1i*2*pi*t *rf.freqOffset)), tFactor*(t0+tc+rf.delay), angle(sc*exp(1i*rf.phaseOffset).*exp(1i*2*pi*tc*rf.freqOffset)),'xb', 'Parent',ax(3));
end
+ % Saving the RF points to compare with Koma
+ sequence{iB}.rf.t = tFactor * (t0 + t_saved + rf.delay);
+ sequence{iB}.rf.A = s_saved * exp(1i*rf.phaseOffset) / koma_gamma;
+ t_saved = [t(1); t(1); t(end); t(end)];
+ sequence{iB}.df.t = tFactor * (t0 + t_saved + rf.delay);
+ sequence{iB}.df.A = [0; rf.freqOffset; rf.freqOffset; 0];
%plot(tFactor*(t0+t+rf.delay), angle( exp(1i*rf.phaseOffset).*exp(1i*2*pi*t *rf.freqOffset)), tFactor*(t0+tc+rf.delay), angle( exp(1i*rf.phaseOffset).*exp(1i*2*pi*t(ic)*rf.freqOffset)),'xb', 'Parent',ax(3));
end
gradChannels={'gx','gy','gz'};
@@ -1331,9 +1354,29 @@ classdef Sequence < handle
%t=grad.delay + [0; grad.t + (grad.t(2)-grad.t(1))/2; grad.t(end) + grad.t(2)-grad.t(1)];
t= grad.delay+[0; grad.tt; grad.shape_dur];
waveform=1e-3* [grad.first; grad.waveform; grad.last];
+ % Saving waveform to compare with Koma
+ t_saved = t;
+ wave_saved = [grad.first; grad.waveform; grad.last];
else
t=cumsum([0 grad.delay grad.riseTime grad.flatTime grad.fallTime]);
waveform=1e-3*grad.amplitude*[0 0 1 1 0];
+ % Saving waveform to compare with Koma
+ t_saved = t(2:end);
+ wave_saved = grad.amplitude*[0 1 1 0];
+ end
+ if sum(abs(waveform)) ~= 0
+ gi_t = tFactor * (t0 + t_saved);
+ gi_A = wave_saved / koma_gamma;
+ if j == 1
+ sequence{iB}.gx.t = gi_t;
+ sequence{iB}.gx.A = gi_A;
+ elseif j == 2
+ sequence{iB}.gy.t = gi_t;
+ sequence{iB}.gy.A = gi_A;
+ elseif j == 3
+ sequence{iB}.gz.t = gi_t;
+ sequence{iB}.gz.A = gi_A;
+ end
end
plot(tFactor*(t0+t),waveform,'Parent',ax(3+j));
end
@@ -1342,6 +1385,9 @@ classdef Sequence < handle
t0=t0+obj.blockDurations(iB);%mr.calcDuration(block);
end
+ filename = strcat('/home/ccp/Documents/KomaMRI.jl/KomaMRIFiles/test/test_files/pulseq_read_comparison/', obj.definitions('FileName'), '.mat');
+ display(filename)
+ save(filename, 'sequence')
% Set axis limits and zoom properties
dispRange = tFactor*[timeRange(1) min(timeRange(2),t0)];
arrayfun(@(x)xlim(x,dispRange),ax); |
It is a good idea to go deeper in the creation of code tests. This really will help to accept the contribution of other guys.
For instance, tests for KomaMRIFiles for pulseq files .seq.
The text was updated successfully, but these errors were encountered: