Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.rst
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,5 @@ Common problems and fixes
=========================
* libXp.so.6 missing (in ubuntu >= 15.10, for example)
This is a known is http://askubuntu.com/questions/719839/libxp-so-6-missing-15-10. The idea is to install it manually from official sources https://launchpad.net/ubuntu/wily/+package/libxp6

* Beware: the pathname for "scratch" (directory for cache) must not contain any space character! This triggered a nasty bug in nipype....
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, this would go in a separate PR as it has nothing to do with spm12 standalon installation or STC.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to learn how to do better PR ;-)
I only have one branch on my fork of pypreprocess. Should I have created
different branches for different dev?

Chris

Christophe Pallier

Contact info: http://www.pallier.org/w/pmwiki.php/Main/Contact

On Sun, Jun 19, 2016 at 1:15 PM, DOHMATOB Elvis [email protected]
wrote:

In README.rst
#231 (comment):

@@ -186,3 +186,5 @@ Common problems and fixes

Ideally, this would go in a separate PR as it has nothing to do with spm12
standalon installation or STC.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/neurospin/pypreprocess/pull/231/files/8caa896e8ea92a2478829bd93dbdbe53d287f26a#r67615081,
or mute the thread
https://github.com/notifications/unsubscribe/ABdbMoFkN-AlBR_VpaTi2BpGIwM8hV9Tks5qNSTjgaJpZM4IqgU1
.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Sun, Jun 19, 2016 at 2:50 PM, Christophe Pallier <
[email protected]> wrote:

In README.rst
#231 (comment):

@@ -186,3 +186,5 @@ Common problems and fixes

I need to learn how to do better PR ;-) I only have one branch on my fork
of pypreprocess. Should I have created different branches for different
dev? Chris

Yes, you want to create different branches for handling different bugs or
feature requests. This way, you can hop from one branch to another, without
running out of sync. Also, ideally, you never work on the master branch :)
. OK roughly, the basic workflow for doing PRs is:

  • you create a new local branch for each new feature you're implementing.
    This may be implementing a new feature, or fixing a small group (possibly a
    singleton) of tightly linked bugs, etc.
    So, you'd run "pull --rebase upstream master && checkout master &&
    checkout -b branch-for-feature-xyz". In your local git configuration
    (.git/config), "upstream" should point to the official
    neurospin/pypreprocess repo, whilst "origin" should point to your forked
    version on github (e.g, mine is https://github.com/dohmatob/pypreprocess).
  • git push -u origin branch-for-feature-xyz, to forward your local changes
    to github
  • on your github pypreprocess repo, github will propose to send a new PR
    neurosin/master <== chris/branch-for-cool-stuff. Confirm, and that's it.
  • do this for any new feature you're implementing, or bug (or small group
    of) you're trying to fix.
    Hope this helps.

… <#m_1057442999557563642_>
-- Christophe Pallier Contact info:
http://www.pallier.org/w/pmwiki.php/Main/Contact
On Sun, Jun 19, 2016 at 1:15 PM, DOHMATOB Elvis _@_.***> wrote: In
README.rst <#231 (comment)
https://github.com/neurospin/pypreprocess/pull/231#discussion_r67615081>:

@@ -186,3 +186,5 @@ Common problems and fixes > =========================


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/neurospin/pypreprocess/pull/231/files/8caa896e8ea92a2478829bd93dbdbe53d287f26a#r67616456,
or mute the thread
https://github.com/notifications/unsubscribe/AAms1NB24AA9F3Xnoh_mviVwwl-sIsIcks5qNTsxgaJpZM4IqgU1
.

Elvis Dohmatob,
sent from my potato...
http://dohmatob.blogspot.fr/, https://team.inria.fr/parietal/elvis/,
https://github.com/dohmatob

47 changes: 47 additions & 0 deletions continuous_integration/install_spm12.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#! /bin/bash
set -e

# set -x # echo on

SPM_ROOT_DIR=~/opt/spm12 # Installation directory

SPM_SRC=spm12_r6685.zip
MCRINST=MCRInstaller.bin

mkdir -p $SPM_ROOT_DIR && cd $SPM_ROOT_DIR

if [ ! -d spm12 ]; then
if [ ! -f ${SPM_SRC} ]; then
wget http://www.fil.ion.ucl.ac.uk/spm/download/restricted/utopia/${SPM_SRC}
fi
unzip -q ${SPM_SRC}
chmod 755 spm12/run_spm12.sh
fi

if [ ! -d mcr ]; then
if [ ! -f MCRInstaller.bin ]; then
wget http://www.fil.ion.ucl.ac.uk/spm/download/restricted/utopia/MCR/glnxa64/${MCRINST}
fi
chmod 755 ${MCRINST}
./${MCRINST} -P bean421.installLocation="mcr" -silent
fi


if [ ! -f $SPM_ROOT_DIR/spm12.sh ]; then
cat <<EOF > $SPM_ROOT_DIR/spm12.sh
#!/bin/bash
SPM12_STANDALONE_HOME=$SPM_ROOT_DIR/spm12
exec "\${SPM12_STANDALONE_HOME}/run_spm12.sh" "\${SPM12_STANDALONE_HOME}/../mcr/v713" \${1+"\$@"}
EOF

chmod 755 $SPM_ROOT_DIR/spm12.sh
fi

# Create CTF
$SPM_ROOT_DIR/spm12.sh quit
cmds="export SPM_DIR=$SPM_ROOT_DIR/spm12/; export SPM_MCR=$SPM_ROOT_DIR/spm12.sh"
${cmds}
echo "You may want to add the following commands (the exports) to your ~/.bashrc file once and for all."
echo
echo ${cmds}

20 changes: 10 additions & 10 deletions pypreprocess/nipype_preproc_spm_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,20 +143,19 @@ def _do_subject_slice_timing(subject_data, TR, TA=None, spm_dir=None,

# compute nslices
nslices = load_vols(subject_data.func[0])[0].shape[2]
assert 1 <= ref_slice <= nslices, ref_slice
# assert 1 <= ref_slice <= nslices, ref_slice

# compute slice indices / order
if not isinstance(slice_order, basestring):
slice_order = np.array(slice_order) - 1
slice_order = get_slice_indices(nslices, slice_order=slice_order,
interleaved=interleaved)
# # compute slice indices / order
# if not isinstance(slice_order, basestring):
# slice_order = np.array(slice_order) - 1
# slice_order = get_slice_indices(nslices, slice_order=slice_order,
# inter leaved=interleaved)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The get_slice_indices function has been fixed for the bug you spotted, so I'd advice using it. It's useful if slice_order == "interleaved", in fact it does general sanitization. See comments on line 197 below.


# use pure python (pp) code ?
if software == "python":
return _pp_do_subject_slice_timing(subject_data, ref_slice=ref_slice,
slice_order=slice_order,
caching=caching)

caching=caching)
# sanitize software choice
if software != "spm":
raise NotImplementedError(
Expand Down Expand Up @@ -193,8 +192,9 @@ def _do_subject_slice_timing(subject_data, TR, TA=None, spm_dir=None,
for sess_func in subject_data.func:
stc_result = stc(in_files=sess_func, time_repetition=TR,
time_acquisition=TA, num_slices=nslices,
ref_slice=ref_slice + 1,
slice_order=list(slice_order + 1), # SPM
ref_slice=ref_slice,
#slice_order=list(slice_order + 1), # SPM8 ?
slice_order=[int(x) for x in slice_order.split()], # SPM12
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • This breaks things. Here you're assuming that slicer_order is a list space-separated string of integers like "1 2 3 4 5". What if it's a list like [1, 2, 3, 4, 5] ? What if it's a string like "ascending" (with the usual meaning) ?
  • The index-generation logic should be factored out and relocated in a testable function like slice_timing.get_indices. The later has been corrected for the bug you spotted (double computing of indices, etc.) and so this refactoring should be smooth.

ignore_exception=False
)
if stc_result.outputs is None:
Expand Down
39 changes: 39 additions & 0 deletions scripts/extract_timings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#! /usr/bin/env python
# Time-stamp: <2016-05-31 14:58:27 chrplr>
#

""" Extracts slice timing information from a dicom file.
To be passed as argument to slice_order for slice timing correction algorithms """

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I remember good, we were considering hosting a small dataset (say on NTRC), that could be used here to make this demo self-contained. Any update ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,

I have put a dataset at:

https://www.nitrc.org/frs/download.php/9035/epi-example-dicom.tar.gz

As soon as spm12 works in the master branch of pypreprocess, I will test it
on this dataset.

I still need to write code to fetch the dataset...

Chris

Christophe Pallier

Contact info: http://www.pallier.org/w/pmwiki.php/Main/Contact

On Sun, Jun 19, 2016 at 1:18 PM, DOHMATOB Elvis [email protected]
wrote:

In scripts/extract_timings.py
#231 (comment):

@@ -0,0 +1,39 @@
+#! /usr/bin/env python
+# Time-stamp: <2016-05-31 14:58:27 chrplr>
+#
+
+""" Extracts slice timing information from a dicom file.
+To be passed as argument to slice_order for slice timing correction algorithms """
+

If I remember good, we were considering hosting a small dataset (say on
NTRC), that could be used here to make this demo self-contained. Any update
?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/neurospin/pypreprocess/pull/231/files/8caa896e8ea92a2478829bd93dbdbe53d287f26a#r67615123,
or mute the thread
https://github.com/notifications/unsubscribe/ABdbMvWtLial8myl397edxDu0Il1GHwSks5qNSWAgaJpZM4IqgU1
.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Sun, Jun 19, 2016 at 2:47 PM, Christophe Pallier <
[email protected]> wrote:

In scripts/extract_timings.py
#231 (comment):

@@ -0,0 +1,39 @@
+#! /usr/bin/env python
+# Time-stamp: <2016-05-31 14:58:27 chrplr>
+#
+
+""" Extracts slice timing information from a dicom file.
+To be passed as argument to slice_order for slice timing correction algorithms """
+

Hi, I have put a dataset at:
https://www.nitrc.org/frs/download.php/9035/epi-example-dicom.tar.gz As
soon as spm12 works in the master branch of pypreprocess,

I've merged a PR which should adress the issue that was raised on spm12 and
mcr stuff, at least in part. My bet is spm12 works now, but it'd be great
if someone with spm12 could confirm.

I will test it on this dataset. I still need to write code to fetch the
dataset... Chris
… <#m_6929222270908548504_>
-- Christophe Pallier Contact info:
http://www.pallier.org/w/pmwiki.php/Main/Contact
On Sun, Jun 19, 2016 at 1:18 PM, DOHMATOB Elvis _@_.***> wrote: In
scripts/extract_timings.py <#231 (comment)
https://github.com/neurospin/pypreprocess/pull/231#discussion_r67615123>:

@@ -0,0 +1,39 @@ > +#! /usr/bin/env python > +# Time-stamp: <2016-05-31
14:58:27 chrplr> > +# > + > +""" Extracts slice timing information from a
dicom file. > +To be passed as argument to slice_order for slice timing
correction algorithms """ > + If I remember good, we were considering
hosting a small dataset (say on NTRC), that could be used here to make this
demo self-contained. Any update ? — You are receiving this because you were
mentioned. Reply to this email directly, view it on GitHub <
https://github.com/neurospin/pypreprocess/pull/231/files/8caa896e8ea92a2478829bd93dbdbe53d287f26a#r67615123>,
or mute the thread <
https://github.com/notifications/unsubscribe/ABdbMvWtLial8myl397edxDu0Il1GHwSks5qNSWAgaJpZM4IqgU1>
.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/neurospin/pypreprocess/pull/231/files/8caa896e8ea92a2478829bd93dbdbe53d287f26a#r67616387,
or mute the thread
https://github.com/notifications/unsubscribe/AAms1CVDE8NveGHlAfF1MMe3rnDqVnrXks5qNTpVgaJpZM4IqgU1
.

Elvis Dohmatob,
sent from my potato...
http://dohmatob.blogspot.fr/, https://team.inria.fr/parietal/elvis/,
https://github.com/dohmatob

Copy link
Contributor Author

@chrplr chrplr Jun 20, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have just tried with a list of integers (slice numbers) for slice_order:

slice_order = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84

and got a crash:

File "/home/cp983411/code/pypreprocess/pypreprocess/slice_timing.py", line 56, in get_slice_indices
raise ValueError("Unknown slice order '%s'!" % slice_order)
ValueError: Unknown slice order '1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84'!

It seems that the list is recognized a a string (isinstance(slice_order, basestring) is True), should I use a list syntax with '[' '],' and ','?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, it works with the python list syntax

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, it crashes further down the line:

     Executing node 34c2260517be663ec808a9998c01a803 in dir: /home/cp983411/epi-example-dicom/essai/nifti/cache_dir/nipype_mem/nipype-interfaces-spm-preprocess-SliceTiming/34c2260517be663ec808a9998c01a803

160620-09:42:23,548 workflow INFO:
Runtime memory and threads stats unavailable
Hardlinked /home/cp983411/epi-example-dicom/nifti/StudyID-001_SeriesNumber-000009_000001ap080059.nii -> /home/cp983411/epi-example-dicom/essai/nifti/StudyID-001_SeriesNumber-000009_000001ap080059.nii ...
/home/cp983411/code/pypreprocess/pypreprocess/nipype_preproc_spm_utils.py:416: UserWarning: subject_data.anat=None (empty); skipping coregistration!
subject_data.anat))
Traceback (most recent call last):
File "/home/cp983411/code/pypreprocess/pypreprocess.py", line 23, in
subjects = do_subjects_preproc(sys.argv[1])
File "/home/cp983411/code/pypreprocess/pypreprocess/nipype_preproc_spm_utils.py", line 1714, in do_subjects_preproc
subject_data, *_preproc_params) for subject_data in subjects)
File "/usr/lib/python2.7/dist-packages/joblib/parallel.py", line 800, in call
while self.dispatch_one_batch(iterator):
File "/usr/lib/python2.7/dist-packages/joblib/parallel.py", line 658, in dispatch_one_batch
self._dispatch(tasks)
File "/usr/lib/python2.7/dist-packages/joblib/parallel.py", line 566, in _dispatch
job = ImmediateComputeBatch(batch)
File "/usr/lib/python2.7/dist-packages/joblib/parallel.py", line 180, in init
self.results = batch()
File "/usr/lib/python2.7/dist-packages/joblib/parallel.py", line 72, in call
return [func(_args, **kwargs) for func, args, kwargs in self.items]
File "/home/cp983411/code/pypreprocess/pypreprocess/nipype_preproc_spm_utils.py", line 1373, in do_subject_preproc
subject_data.hardlink_output_files(final=True)
File "/home/cp983411/code/pypreprocess/pypreprocess/subject_data.py", line 451, in hardlink_output_files
setattr(self, item, linked_filename)
UnboundLocalError: local variable 'linked_filename' referenced before assignment

But this maybe because it is an unsual use case (?). For the *.ini:

#%
disable_realign = True
disable_coregister = True
disable_segment = True
disable_normalize = True
disable_smooth = True

output_dir = essai
report = False
plot_tsdiffana = False

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Mon, Jun 20, 2016 at 9:34 AM, Christophe Pallier <
[email protected]> wrote:

In scripts/extract_timings.py
#231 (comment):

@@ -0,0 +1,39 @@
+#! /usr/bin/env python
+# Time-stamp: <2016-05-31 14:58:27 chrplr>
+#
+
+""" Extracts slice timing information from a dicom file.
+To be passed as argument to slice_order for slice timing correction algorithms """
+

I have just tried with a list of integers (slice numbers) for slice_order
and got a crash:

File "/home/cp983411/code/pypreprocess/pypreprocess/slice_timing.py", line
56, in get_slice_indices
raise ValueError("Unknown slice order '%s'!" % slice_order)
ValueError: Unknown slice order '1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84'!

This is because the only allowed strings are "ascending" or "descending".
Otherwise it must be a list of integers. I'm updating the docstring for
this function to make this clearer. In summary, the logic for converting a
string of of integers (e.g "0 1 2 3 4") into a list of into a list of
integers ([0, 1, 2, 3, 4]) should be done out-side this function.

It seems that the list is recognized a a string (isinstance(slice_order,
basestring) is True), should I use a list syntax with '[' '],' and ','?


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/neurospin/pypreprocess/pull/231/files/8caa896e8ea92a2478829bd93dbdbe53d287f26a#r67646509,
or mute the thread
https://github.com/notifications/unsubscribe/AAms1G1As_V6SfsEg5e5RKBnQLsQMxl_ks5qNkKigaJpZM4IqgU1
.

Elvis Dohmatob,
sent from my potato...
http://dohmatob.blogspot.fr/, https://team.inria.fr/parietal/elvis/,
https://github.com/dohmatob

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Mon, Jun 20, 2016 at 9:46 AM, Christophe Pallier <
[email protected]> wrote:

In scripts/extract_timings.py
#231 (comment):

@@ -0,0 +1,39 @@
+#! /usr/bin/env python
+# Time-stamp: <2016-05-31 14:58:27 chrplr>
+#
+
+""" Extracts slice timing information from a dicom file.
+To be passed as argument to slice_order for slice timing correction algorithms """
+

well, it crashes further down the line:

 Executing node 34c2260517be663ec808a9998c01a803 in dir: /home/cp983411/epi-example-dicom/essai/nifti/cache_dir/nipype_mem/nipype-interfaces-spm-preprocess-SliceTiming/34c2260517be663ec808a9998c01a803

160620-09:42:23,548 workflow INFO:
Runtime memory and threads stats unavailable
Hardlinked
/home/cp983411/epi-example-dicom/nifti/StudyID-001_SeriesNumber-000009_000001ap080059.nii
->
/home/cp983411/epi-example-dicom/essai/nifti/StudyID-001_SeriesNumber-000009_000001ap080059.nii
...
/home/cp983411/code/pypreprocess/pypreprocess/nipype_preproc_spm_utils.py:416:
UserWarning: subject_data.anat=None (empty); skipping coregistration!
subject_data.anat))
Traceback (most recent call last):
File "/home/cp983411/code/pypreprocess/pypreprocess.py", line 23, in
subjects = do_subjects_preproc(sys.argv[1])
File
"/home/cp983411/code/pypreprocess/pypreprocess/nipype_preproc_spm_utils.py",
line 1714, in do_subjects_preproc
subject_data, *

_preproc_params) for subject_data in subjects) File
"/usr/lib/python2.7/dist-packages/joblib/parallel.py", line 800, in call
while self.dispatch_one_batch(iterator): File
"/usr/lib/python2.7/dist-packages/joblib/parallel.py", line 658, in
dispatch_one_batch self.dispatch(tasks) File
"/usr/lib/python2.7/dist-packages/joblib/parallel.py", line 566, in
dispatch job = ImmediateComputeBatch(batch) File
"/usr/lib/python2.7/dist-packages/joblib/parallel.py", line 180, in __init
self.results = batch() File
"/usr/lib/python2.7/dist-packages/joblib/parallel.py", line 72, in call
return [func(_args, **kwargs) for func, args, kwargs in self.items]
File
"/home/cp983411/code/pypreprocess/pypreprocess/nipype_preproc_spm_utils.py",
line 1373, in do_subject_preproc
subject_data.hardlink_output_files(final=True)
File "/home/cp983411/code/pypreprocess/pypreprocess/subject_data.py", line
451, in hardlink_output_files
setattr(self, item, linked_filename)
UnboundLocalError: local variable 'linked_filename' referenced before
assignment

OK this is an indentation bug introduced by PR #230. Ping @mrahim. The
existence of such bugs in master tells us we badly lack code-coverage. I'm
rolling a fix for this.

But this maybe because it is an unsual use case (?). For the *.ini:

#%
disable_realign = True
disable_coregister = True
disable_segment = True
disable_normalize = True
disable_smooth = True

output_dir = essai
report = False
plot_tsdiffana = False


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/neurospin/pypreprocess/pull/231/files/8caa896e8ea92a2478829bd93dbdbe53d287f26a#r67647592,
or mute the thread
https://github.com/notifications/unsubscribe/AAms1MZQcVV47-sRFUwLs9bD0tyRfTLuks5qNkU-gaJpZM4IqgU1
.

Elvis Dohmatob,
sent from my potato...
http://dohmatob.blogspot.fr/, https://team.inria.fr/parietal/elvis/,
https://github.com/dohmatob

from __future__ import print_function
import os
import glob
import dicom
import sys

try:
dicom_path = sys.argv[1]

if os.path.isdir(dicom_path):
dicom_ref = sorted(glob.glob(os.path.join(dicom_path, '*.dcm')))[4]
else:
if (os.path.isfile(dicom_path)):
dicom_ref = dicom_path

TR = dicom.read_file(dicom_ref).RepetitionTime
slice_times = dicom.read_file(dicom_ref)[0x19, 0x1029].value
nb_slices = len(slice_times)

except:
print("Unexpected error: %s" % sys.exc_info()[0])
print("\nUsage:\n %s dicom_path\nWhere dicom_path is a dicom directory" % sys.argv[0])
sys.exit(-1)

print("TR = %.3f" % (TR/1000.))
#print("nb_slices = %d" % nb_slices)
print("slice_timings = ", end=" ")
for v in slice_times:
print("%.1f" % v, end=" ")
print("\n", end="")
print("refslice = %.3f" % (TR/2000.))