forked from toppeMRI/toppe
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
140 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,97 +1,130 @@ | ||
function coppe(varargin) | ||
% function coppe(varargin) | ||
% Function for **internal** University of Michigan fMRI lab use only to | ||
% send toppe files automatically to our scanners. Can be generalized for | ||
% other sites but the server names need to be updated. | ||
% | ||
% A rough copy of the bash script called in this function (pushtoppefiles) | ||
% that we have on lab servers that can access the scanner is the | ||
% following: | ||
% | ||
% #!/bin/bash | ||
% # Support file for copying toppe scan files to the scanner, then unpacking them | ||
% set -e | ||
% IP=$(getscannerip) | ||
% echo "Copying files to scanner..." | ||
% ssh sdc@$IP 'scp fmrilab@toro:~/toppe_utils/toppe-scanfiles.tgz /usr/g/bin/; cd /usr/g/bin/; tar -xzf toppe-scanfiles.tgz' | ||
% | ||
% Function for **internal** University of Michigan fMRI lab use only to | ||
% send toppe files automatically to our scanners. Can be generalized for | ||
% other sites but the server names need to be updated. | ||
% | ||
% Input options: | ||
% target which scanner to copy pulse sequence to, UM options: 'inside', 'outside' | ||
% use_pw option to allow command line input, in the case a pw is needed | ||
% cv CV number, used to determing where on the scanner to put files | ||
% cv CV number, used to determing where on the scanner to put files | ||
% target which scanner to copy pulse sequence to, UM options: 'inside', 'outside' | ||
% force option to force overwrite of existing sequences corresponding | ||
% to cv (default is 0, no overwrite) | ||
% user user name on server to use for file transfer (defaults to current user name) | ||
% use_pw option to allow command line input, in the case a pw is needed | ||
% (default is 0) | ||
% dir target directory to write to under /srv/nfs/psd/usr/psd on scanner | ||
% (default is [username]/toppe[cv #]) | ||
% version toppe software version (5 for tv5, 6 for tv6) | ||
% | ||
% Packages toppe files into toppe-scanfiles.tgz, then copies it to the scanner | ||
% Assumes you have SSH keys set up to log into romero/toro | ||
|
||
import toppe.utils.* | ||
|
||
arg.target = 'inside'; % Default to inside scanner | ||
arg.use_pw = false; % assume we have ssh keys setup to not need a pw | ||
arg.cv = []; % if no CV given, it will coppe to /usr/g/bin | ||
arg = vararg_pair(arg, varargin); | ||
% Assumes you have the following SSH keys set up: | ||
% 1. ssh key from host --> server | ||
% 2. ssh key from scanner --> host | ||
% | ||
% if SSH keys require a passcode, set use_pw = 1 to show prompt | ||
% | ||
|
||
fprintf('Making archive...'); | ||
[status,cmdout] = system('tar czf toppe-scanfiles.tgz modules.txt seqstamp.txt scanloop.txt *.mod'); fprintf('done!\n'); | ||
import toppe.utils.* | ||
basedir = '/srv/nfs/psd/usr/psd'; % base directory on scanner | ||
|
||
% Set default arguments | ||
arg.target = 'inside'; | ||
arg.force = 0; | ||
[~,arg.user] = system('echo -n $USER'); | ||
arg.use_pw = 0; | ||
arg.cv = []; | ||
arg.dir = 'auto'; | ||
arg.version = 6; %Toppe version | ||
arg = vararg_pair(arg, varargin); | ||
|
||
if status | ||
error(cmdout) | ||
end | ||
% set the default target directory | ||
if strcmpi(arg.dir,'auto') | ||
arg.dir = sprintf('%s/toppe%d', arg.user, arg.cv); | ||
end | ||
|
||
% Create string for calling bash script on server | ||
if isempty(arg.cv) | ||
script2call = 'pushtoppefiles'; | ||
else | ||
script2call = ['pushtoppefiles ', num2str(arg.cv)]; | ||
end | ||
% get the host IP address | ||
[~,host_IP] = system('wget -qO- ifconfig.me/ip'); | ||
|
||
% zip the sequence using tar | ||
fprintf('Zipping toppe files using tar...'); | ||
if(arg.version < 6) | ||
[status,cmdout] = system('tar czf toppe-scanfiles.tgz modules.txt seqstamp.txt scanloop.txt *.mod'); | ||
else | ||
[status,cmdout] = system('tar czf toppe-scanfiles.tgz modules.txt seqstamp.txt scanloop.txt cores.txt toppeN.entry *.mod'); | ||
end | ||
if status | ||
error(cmdout) | ||
else | ||
fprintf(' SUCCESS\n'); | ||
end | ||
|
||
try | ||
% set server names | ||
switch arg.target | ||
case 'inside' | ||
server_str = 'romero'; | ||
homedir_str = '/export/home/fmrilab'; | ||
server_str = 'epyc'; | ||
case 'outside' | ||
server_str = 'toro'; | ||
homedir_str = '/home/fmrilab'; | ||
server_str = 'goliath'; | ||
otherwise | ||
fprintf('Invalid target, valid targets are ''inside'' or ''outside''.\n'); | ||
error('Invalid target, valid targets are ''inside'' or ''outside''.\n'); | ||
end | ||
|
||
%% create linux commands with correct server target and run | ||
|
||
cmd1 = ['scp toppe-scanfiles.tgz fmrilab@',server_str,':~/toppe_utils/']; | ||
cmd2 = ['ssh -q fmrilab@',server_str,' ',homedir_str,'/toppe_utils/', script2call]; | ||
|
||
% 1. Send toppe files to server | ||
fprintf(['Copying to ',server_str,'...']); | ||
if ~arg.use_pw | ||
[st1, cmdo1] = system(cmd1); | ||
else | ||
[st1, cmdo1] = system(cmd1,'-echo'); | ||
% Set up the commands to run on the scanner | ||
cmd_scanner = []; | ||
if ~arg.force | ||
% check for existing entry file | ||
cmd_scanner = sprintf('%s if [[ -f %s/pulseq/toppe%d.entry ]]; then exit 15; fi;', ... | ||
cmd_scanner, basedir, arg.cv); | ||
end | ||
if st1, error(cmdo1); end; fprintf('done!\n'); | ||
% check if directory exists, if it doesn't, create it | ||
cmd_scanner = sprintf('%s if [ ! -d %s/%s ]; then mkdir -p %s/%s; fi;', ... | ||
cmd_scanner, basedir, arg.dir, basedir, arg.dir); | ||
% cd into the directory | ||
cmd_scanner = sprintf('%s if ! cd %s/%s; then exit 16; fi;', ... | ||
cmd_scanner, basedir, arg.dir); | ||
% scp toppe files from host | ||
cmd_scanner = sprintf('%s if ! scp -q %s@%s:%s/toppe-scanfiles.tgz ./; then exit 17; fi;', ... | ||
cmd_scanner, arg.user, host_IP, pwd); | ||
% unzip the tar file | ||
cmd_scanner = sprintf('%s if ! tar -xzf toppe-scanfiles.tgz; then exit 18; fi; rm toppe-scanfiles.tgz;', ... | ||
cmd_scanner); | ||
% rename the entry file and move it to pulseq directory | ||
cmd_scanner = sprintf('%s if ! mv toppeN.entry %s/pulseq/v%d/toppe%d.entry; then exit 19; fi;', ... | ||
cmd_scanner, basedir, arg.version,arg.cv); | ||
% replace the first line with the right directory | ||
cmd_scanner = sprintf('%s if ! sed -i "1s#.*#%s/%s/#" %s/pulseq/v%d/toppe%d.entry; then exit 20; fi;', ... | ||
cmd_scanner, basedir, arg.dir, basedir, arg.version, arg.cv); | ||
|
||
% ssh into server, then into scanner, and run the scanner commands using bash | ||
cmd_host = sprintf('ssh -q %s@%s ssh -q sdc@10.0.1.1 /bin/bash << EOF\n%s\nEOF', ... | ||
arg.user, server_str, cmd_scanner); | ||
|
||
% 2. Send toppe files from server to scanner computer and untar | ||
fprintf('Copying to scanner and untaring ...'); | ||
if ~arg.use_pw | ||
[st2, cmdo2] = system(cmd2); | ||
% use -echo to show the bash output (in case pw is required) | ||
if arg.use_pw | ||
eval_args = {cmd_host, '-echo'}; | ||
else | ||
[st2, cmdo2] = system(cmd2,'-echo'); | ||
eval_args = {cmd_host}; | ||
end | ||
if st2, error(cmdo2); end; fprintf('done!\n'); | ||
|
||
|
||
%% Find minimum number of slices | ||
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 or greater.\n',max_sli+1); | ||
|
||
disp('Ready to scan.'); | ||
catch | ||
fprintf('\n...failed. Not ready to scan.\n'); | ||
|
||
% Copy the file to the scanner and unzip | ||
fprintf('Copying to scanner and unzipping...'); | ||
[out,msg] = system(eval_args{:}); | ||
switch out | ||
case 15 | ||
error('cv number %d is already taken, use force argument to force overwrite', arg.cv); | ||
case 16 | ||
error('failed to cd into %s/%s\noutput:\n%s', basedir, arg.dir, msg) | ||
case 17 | ||
error('failed to scp from host to scanner, are your keys set up right?\noutput:\n%s', msg) | ||
case 18 | ||
error('failed to unzip the tar file\noutput:\n%s', msg) | ||
case 19 | ||
error('failed to move the entry file\noutput:\n%s', msg) | ||
case 0 | ||
fprintf(' SUCCESS\nsequence files written to %s/%s\n', basedir, arg.dir); | ||
otherwise | ||
error('unknown error\noutput:\n%s',msg) | ||
end | ||
|
||
end | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
function [kxo, kxe] = getk(sysGE, readoutFile, nfid, del) | ||
% Get kspace sample locations from .mod file | ||
% | ||
% Inputs: | ||
% sysGE see toppe.systemspecs() | ||
% readoutFile .mod file name containing ADC window | ||
% nfid number of acquired samples in ADC window | ||
% | ||
% Option: | ||
% del offset by this many samples (default: 0) | ||
% | ||
% Outputs: | ||
% kxo [1 nfid], odd echo k-space, cycles/cm | ||
% kxe [1 nfid], even echo k-space, cycles/cm | ||
|
||
if nargin < 4 | ||
del = 0.0; | ||
end | ||
|
||
[rf,gx,gy,gz,desc,paramsint16,paramsfloat,hdr] = toppe.readmod(readoutFile); | ||
kx = sysGE.raster*1e-6*sysGE.gamma*1e-4*cumsum(gx); % cycles/cm | ||
kx = kx - kx(end)/2; | ||
kx = kx((hdr.npre+1):(hdr.npre+nfid)); | ||
kxo = interp1(1:nfid, kx, (1:nfid) - 0.5 - del, 'linear', 'extrap'); | ||
kxe = interp1(1:nfid, kx, (1:nfid) + 0.5 + del, 'linear', 'extrap'); | ||
kxe = fliplr(kxe); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters