Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
Sync'd .m files in toppe.* and toppe.utils.* with UM gitlab repo (master branch)
  • Loading branch information
jon committed Aug 28, 2020
2 parents 1166e63 + 8f837f5 commit 6c02b6f
Show file tree
Hide file tree
Showing 19 changed files with 524 additions and 157 deletions.
49 changes: 42 additions & 7 deletions +toppe/+utils/coppe.m
Original file line number Diff line number Diff line change
@@ -1,11 +1,46 @@
function coppe(varargin)
% function coppe(varargin)
%
% Load data for one echo (or all) from Pfile, EXCEPT dabslice=0 slot (which can contain corrupt data).
%
% Input options:
% target which scanner to copy pulse sequence to
% options: 'inside', 'outside'
%
% Packages toppe files into toppe-scanfiles.tgz, then copies it to the scanner
% Assumes you have SSH keys set up to log into romero
% Pretty much for UM fMRI lab use only...
% Assumes you have SSH keys set up to log into romero/toro
% For UM fMRI lab use only...

import toppe.utils.*

arg.target = 'inside'; % Default to inside scanner
arg = vararg_pair(arg, varargin);

fprintf('Making archive...');
[~,~] = system('tar czf toppe-scanfiles.tgz modules.txt scanloop.txt *.mod'); fprintf('done!\n');
fprintf('Copying to romero...');
[~,~] = system('scp toppe-scanfiles.tgz fmrilab@romero:~/amos/'); fprintf('done!\n');
fprintf('Copying to scanner...');
[~,~] = system('ssh -q fmrilab@romero "~/amos/pushtoppefiles"'); fprintf('done!\n');
disp('Ready to scan.');

try
switch arg.target
case 'inside'
fprintf('Copying to romero...');
[~,~] = system('scp toppe-scanfiles.tgz fmrilab@romero:~/amos/'); fprintf('done!\n');
fprintf('Copying to scanner...');
[~,~] = system('ssh -q fmrilab@romero "~/amos/pushtoppefiles"'); fprintf('done!\n');

case 'outside'
fprintf('Copying to toro...');
[~,~] = system('scp toppe-scanfiles.tgz fmrilab@toro:~/tmp_amos/'); fprintf('done!\n');
fprintf('Copying to scanner...');
[~,~] = system('ssh -q fmrilab@toro "~/tmp_amos/pushtoppefiles"'); fprintf('done!\n');
otherwise
fprintf('Invalid target, valid targets are ''inside'' or ''outside''.\n');
end
disp('Files sucessfully copied. Finding # of slices...');
scanloop_struc = importdata('scanloop.txt');
scanloop_struc_data = scanloop_struc.data;
max_sli = scanloop_struc_data(2);
fprintf('Set # of slices on scanner to %d.\n',max_sli+1);
disp('Ready to scan.');
catch
fprintf('\n...failed. Not ready to scan.\n');
end
10 changes: 5 additions & 5 deletions +toppe/+utils/fail.m
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
function fail(varargin)
%function fail(varargin)
%|function fail(varargin)
%|
%| fail with concise but informative error message.
%| the motivation for this routine is that sometimes matlab's error command
%| annoyingly does not tell the file/line where the error occured.
%| this call ensures that the file/line is always displayed.

[name, line] = toppe.utils.caller_name(1);
if isempty(varargin)
toppe.utils.printf('Fail: %s %d', name, line)
[name line] = caller_name(1);
if length(varargin)
printf(['Fail: %s %d: ' varargin{1}], name, line, varargin{2:end})
else
toppe.utils.printf(['Fail: %s %d: ' varargin{1}], name, line, varargin{2:end})
printf(['Fail: %s %d'], name, line)
end
%error fail
evalin('caller', 'error(''!'')')
73 changes: 73 additions & 0 deletions +toppe/+utils/getSTFRtiming.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
function [Tfree Tg TE] = getSTFRtiming(TEro, varargin)
% function [Tfree Tg TE] = getSTFRtiming(TEro, varargin)
%
% Calculate TR/Tfree/Tg/TE for an STFR sequence.
% Sequence is assumed to consist of tipdown-readout-tipup-spoiler modules.
%
% The file 'modules.txt' must exist in the current folder, and must contain the .mod files
% passed to this function.
%
% NB! Overwrites scanloop.txt in current folder.
%
% Inputs:
% TEro double Time from beginning of readout to echo (ms)
% Input options:
% tipdown [string] .mod file name containing tipdown excitation pulse. Default: 'tipdown.mod'
% readout [string] .mod file containing readout. Default: 'readout.mod'
% tipup [string] .mod file name containing tipup excitation pulse. Default: 'tipup.mod'
% sys struct System hardware specs. See toppe.systemspecs. Default: sys = toppe.systemspecs();
%
% Outputs:
% TR double Sequence TR (ms)
% Tfree double Time from peak of tipdown pulse to peak of tipup pulse (ms)
% Tg double Time from peak of tipup pulse to peak of tipdown pulse (ms)
% TE double Time to echo (ms)
%
% Example:
% >> [~,~,~,~,~,hdrints] = toppe.readmod('readout.mod');
% >> sys = toppe.systemspecs();
% >> TEro = 1e-3*(sys.toppe.start_core_daq + sys.toppe.daqdel + hdrints(3)*4); % ms
% >> [TR, Tfree, Tg, TE] = toppe.utils.getSTFRtiming(TEro, 'tipdown', 'tipdown,1.mod', 'readout', 'readout,1.mod', 'tipup', 'tipup,1.mod', 'spoiler', 'spoiler,1.mod');


% defaults
arg.tipdown = 'tipdown.mod';
arg.readout = 'readout.mod';
arg.tipup = 'tipup.mod';
arg.spoiler = 'spoiler.mod';
arg.system = toppe.systemspecs();

% parse inputs
arg = toppe.utils.vararg_pair(arg, varargin);

dt = 4e-3; % ms

% write scanloop.txt
toppe.write2loop('setup');
toppe.write2loop(arg.tipdown);
toppe.write2loop(arg.readout);
toppe.write2loop(arg.tipup);
toppe.write2loop(arg.spoiler);
toppe.write2loop('finish');

% Tfree
rf = toppe.plotseq(1, 1, 'doDisplay', false, 'system', arg.system);
n1 = length(rf); % length of tipdown
rf = toppe.plotseq(2, 3, 'doDisplay', false, 'system', arg.system);
n2 = length(rf); % length of readout+tipup
rf = toppe.plotseq(1, 3, 'doDisplay', false, 'system', arg.system);
I = find(abs(rf(1:n1))==max(abs(rf(1:n1))));
itipdown = I(1); % the peak can contain more than one sample
I = find(abs(rf(n1:end))==max(abs(rf(n1:end))));
itipup = I(1) + n1;
Tfree = dt*(itipup-itipdown);

tipdown.dur = dt*n1; % ms
tipdown.tpeak = dt*itipdown; % ms

% Tg
rf = toppe.plotseq(1, 4, 'doDisplay', false, 'system', arg.system);
Tg = dt*length(rf) - Tfree;

% TE
TE = (tipdown.dur-tipdown.tpeak) + TEro;
50 changes: 50 additions & 0 deletions +toppe/+utils/getsedelays.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
function [delay90 delay180] = getsedelays(tipdown, refocus, readout, te)
% Calculate delays needed to achieve a desired TE in a spin-echo train.
% Sequence is assumed to consist of tipdown-refocus-readout-refocus-readout-refocus...

% Inputs:
% tipdown [string] .mod file name containing 90 degree excitation pulse
% refocus [string] .mod file containing 180 refocusing pulse
% readout [string] .mod file containing readout
% te [1 1] desired TE (ms)
%
% Outputs:
% delay90 [1 1] (ms). Apply after 90 pulse
% delay180 [1 1] (ms). Apply before AND after 180 pulses
%

dt = 4e-3; % ms

% get minimum TE
toppe.write2loop('setup');
toppe.write2loop(tipdown);
toppe.write2loop(refocus);
toppe.write2loop(readout);
toppe.write2loop(refocus);
toppe.write2loop('finish');
minsep180 = toppe.getTRtime(2,3)*1e3; % ms. Minimum separation between 180 pulses.

% return required delay of 180 pulse (to achieve desired TE)
if minsep180 > te
error('Minimum separation between 180 refocusing pulses exceeds requested TE');
else
delay180 = (te-minsep180)/2;
end

% get separation of 90 pulse and first 180 pulse
rf = toppe.plotseq(1, 1, 'doDisplay', false);
n1 = length(rf); % length of 90 module
rf = toppe.plotseq(2, 2, 'doDisplay', false);
n2 = length(rf); % length of spin-echo module

rf = toppe.plotseq(1, 2, 'doDisplay', false);
i90 = find(abs(rf(1:n1))==max(abs(rf(1:n1))));
i90 = i90(1); % the peak can contain more than one sample
I = find(abs(rf(n1:end))==max(abs(rf(n1:end))));
i180 = I(1) + n1;
minsep90180 = dt*(i180-i90);
if minsep90180 > te/2
error('Minimum separation between 90 and first 180 pulse exceeds requested TE');
else
delay90 = te/2 - minsep90180;
end
2 changes: 2 additions & 0 deletions +toppe/+utils/ift3.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
% >> size(D) = [64 64 16]; ims = ift3(D, 'type', 2d); % 16 receive coils; returns multi-coil 2D images
% >> size(D) = [64 64 20]; ims = ift3(D, 'dozfft', false); % does not do ift along kz; returns 3D image
%
% $Id: ift3.m,v 1.4 2018/10/26 21:46:41 jfnielse Exp $
% $Source: /export/home/jfnielse/Private/cvs/projects/psd/toppe/matlab/+toppe/+utils/ift3.m,v $

import toppe.*
import toppe.utils.*
Expand Down
8 changes: 6 additions & 2 deletions +toppe/+utils/makegre.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
% system struct specifying system info, see systemspecs.m
% ofname Output file name. Default: 'readout.mod'
% extrafiles [bool] If true, writes z phase-encode and spoiler to separate .mod files.
% slewDerate
% slewDerate Reduce slew rate by this factor during prewinders/crushers

zres = zres*10; % mm

Expand Down Expand Up @@ -73,7 +73,11 @@
if arg.ncycles > 0
areacrush = sum(gcrush)*dt*1e-3; % G/cm*sec
arearo = sum([gxprew ramp gxro fliplr(ramp)])*dt*1e-3;
bridge = mybridged(areacrush-arearo,gxro(end), mxg, arg.slewDerate*mxs/sqrt(3)*1e3);
if areacrush > arearo
bridge = mybridged(areacrush-arearo,gxro(end), mxg, arg.slewDerate*mxs/sqrt(3)*1e3);
else
bridge = [];
end
gx = [gxprew ramp gxro bridge fliplr(ramp)];
else
gx = [ramp gxro fliplr(ramp)];
Expand Down
Loading

0 comments on commit 6c02b6f

Please sign in to comment.