-
Notifications
You must be signed in to change notification settings - Fork 39
/
Copy pathrecon_ismrmrd_dataset.py
121 lines (100 loc) · 3.66 KB
/
recon_ismrmrd_dataset.py
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# coding: utf-8
import os
import ismrmrd
import ismrmrd.xsd
import numpy as np
from ismrmrdtools import show, transform
# Load file
filename = '/tmp/testdata.h5'
if not os.path.isfile(filename):
print("%s is not a valid file" % filename)
raise SystemExit
dset = ismrmrd.Dataset(filename, 'dataset', create_if_needed=False)
header = ismrmrd.xsd.CreateFromDocument(dset.read_xml_header())
enc = header.encoding[0]
# Matrix size
eNx = enc.encodedSpace.matrixSize.x
eNy = enc.encodedSpace.matrixSize.y
eNz = enc.encodedSpace.matrixSize.z
rNx = enc.reconSpace.matrixSize.x
rNy = enc.reconSpace.matrixSize.y
rNz = enc.reconSpace.matrixSize.z
# Field of View
eFOVx = enc.encodedSpace.fieldOfView_mm.x
eFOVy = enc.encodedSpace.fieldOfView_mm.y
eFOVz = enc.encodedSpace.fieldOfView_mm.z
rFOVx = enc.reconSpace.fieldOfView_mm.x
rFOVy = enc.reconSpace.fieldOfView_mm.y
rFOVz = enc.reconSpace.fieldOfView_mm.z
# Number of Slices, Reps, Contrasts, etc.
ncoils = header.acquisitionSystemInformation.receiverChannels
if enc.encodingLimits.slice != None:
nslices = enc.encodingLimits.slice.maximum + 1
else:
nslices = 1
if enc.encodingLimits.repetition != None:
nreps = enc.encodingLimits.repetition.maximum + 1
else:
nreps = 1
if enc.encodingLimits.contrast != None:
ncontrasts = enc.encodingLimits.contrast.maximum + 1
else:
ncontrasts = 1
# TODO loop through the acquisitions looking for noise scans
firstacq=0
for acqnum in range(dset.number_of_acquisitions()):
acq = dset.read_acquisition(acqnum)
# TODO: Currently ignoring noise scans
if acq.isFlagSet(ismrmrd.ACQ_IS_NOISE_MEASUREMENT):
print("Found noise scan at acq ", acqnum)
continue
else:
firstacq = acqnum
print("Imaging acquisition starts acq ", acqnum)
break
# Initialiaze a storage array
all_data = np.zeros((nreps, ncontrasts, nslices, ncoils, eNz, eNy, rNx), dtype=np.complex64)
# Loop through the rest of the acquisitions and stuff
for acqnum in range(firstacq,dset.number_of_acquisitions()):
acq = dset.read_acquisition(acqnum)
# TODO: this is where we would apply noise pre-whitening
# Remove oversampling if needed
if eNx != rNx:
xline = transform.transform_kspace_to_image(acq.data, [1])
x0 = (eNx - rNx) / 2
x1 = (eNx - rNx) / 2 + rNx
xline = xline[:,x0:x1]
acq.resize(rNx,acq.active_channels,acq.trajectory_dimensions)
acq.center_sample = rNx/2
# need to use the [:] notation here to fill the data
acq.data[:] = transform.transform_image_to_kspace(xline, [1])
# Stuff into the buffer
rep = acq.idx.repetition
contrast = acq.idx.contrast
slice = acq.idx.slice
y = acq.idx.kspace_encode_step_1
z = acq.idx.kspace_encode_step_2
all_data[rep, contrast, slice, :, z, y, :] = acq.data
# Reconstruct images
images = np.zeros((nreps, ncontrasts, nslices, eNz, eNy, rNx), dtype=np.float32)
for rep in range(nreps):
for contrast in range(ncontrasts):
for slice in range(nslices):
# FFT
if eNz>1:
#3D
im = transform.transform_kspace_to_image(all_data[rep,contrast,slice,:,:,:,:], [1,2,3])
else:
#2D
im = transform.transform_kspace_to_image(all_data[rep,contrast,slice,:,0,:,:], [1,2])
# Sum of squares
im = np.sqrt(np.sum(np.abs(im) ** 2, 0))
# Stuff into the output
if eNz>1:
#3D
images[rep,contrast,slice,:,:,:] = im
else:
#2D
images[rep,contrast,slice,0,:,:] = im
# Show an image
show.imshow(np.squeeze(images[0,0,0,:,:,:]))