Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
William Clarke
pymapVBVD
Commits
576f3ccf
Commit
576f3ccf
authored
Sep 22, 2020
by
Mo Shahdloo
Browse files
post-merge fixes
parent
4af385d4
Changes
4
Hide whitespace changes
Inline
Side-by-side
mapVBVD/__init__.py
View file @
576f3ccf
from
mapVBVD.mapVBVD
import
mapVBVD
from
mapVBVD.read_twix_hdr
import
read_twix_hdr
from
mapVBVD.twix_map_obj
import
twix_map_obj
from
._version
import
get_versions
__version__
=
get_versions
()[
'version'
]
del
get_versions
mapVBVD/_version.py
View file @
576f3ccf
...
...
@@ -43,7 +43,7 @@ def get_config():
cfg
.
style
=
"pep440"
cfg
.
tag_prefix
=
""
cfg
.
parentdir_prefix
=
""
cfg
.
versionfile_source
=
"
mapVBVD
/_version.py"
cfg
.
versionfile_source
=
"
core
/_version.py"
cfg
.
verbose
=
False
return
cfg
...
...
mapVBVD/mapVBVD.py
View file @
576f3ccf
import
numpy
as
np
from
dataclasses
import
dataclass
,
field
import
mapVBVD
as
pkg
from
mapVBVD.read_twix_hdr
import
read_twix_hdr
from
mapVBVD.twix_map_obj
import
twix_map_obj
from
dataclasses
import
dataclass
,
field
from
core
import
mapVBVD
as
pkg
from
attrdict
import
AttrDict
,
AttrMap
,
AttrDefault
from
tqdm
import
tqdm
,
trange
...
...
@@ -65,7 +63,8 @@ def loop_mdh_read(fid, version, Nscans, scan, measOffset, measLength):
dmaOff
=
0
dmaSkip
=
byteMDH
t
=
tqdm
(
total
=
np
.
float
(
str
(
'%8.1f'
%
(
measLength
/
1024
**
2
))),
desc
=
'Scan %d/%d, read all mdhs'
%
(
scan
+
1
,
Nscans
),
leave
=
True
)
t
=
tqdm
(
total
=
np
.
float
(
str
(
'%8.1f'
%
(
measLength
/
1024
**
2
))),
desc
=
'Scan %d/%d, read all mdhs'
%
(
scan
+
1
,
Nscans
),
leave
=
True
)
while
True
:
# Read mdh as binary (uint8) and evaluate as little as possible to know...
# ... where the next mdh is (ulDMALength / ushSamplesInScan & ushUsedChannels)
...
...
@@ -129,18 +128,18 @@ def loop_mdh_read(fid, version, Nscans, scan, measOffset, measLength):
# grow arrays in batches
if
n_acq
>
szBlob
:
grownArray
=
np
.
zeros
((
mdh_blob
.
shape
[
0
],
allocSize
),
dtype
=
np
.
uint8
)
# pylint: disable=E1136 # pylint/issues/3139
mdh_blob
=
np
.
concatenate
((
mdh_blob
,
grownArray
),
axis
=
1
)
grownArray
=
np
.
zeros
((
mdh_blob
.
shape
[
0
],
allocSize
),
dtype
=
np
.
uint8
)
# pylint: disable=E1136 # pylint/issues/3139
mdh_blob
=
np
.
concatenate
((
mdh_blob
,
grownArray
),
axis
=
1
)
filePos
=
np
.
concatenate
((
filePos
,
np
.
zeros
((
allocSize
))),
axis
=
0
)
szBlob
=
mdh_blob
.
shape
[
1
]
# pylint: disable=E1136 # pylint/issues/3139
mdh_blob
[:,
n_acq
-
1
]
=
data_u8
filePos
[
n_acq
-
1
]
=
cPos
filePos
=
np
.
concatenate
((
filePos
,
np
.
zeros
((
allocSize
))),
axis
=
0
)
t
.
update
(
np
.
float
(
str
(
'%8.1f'
%
(
cPos
/
1024
**
2
))))
szBlob
=
mdh_blob
.
shape
[
1
]
# pylint: disable=E1136 # pylint/issues/3139
mdh_blob
[:,
n_acq
-
1
]
=
data_u8
filePos
[
n_acq
-
1
]
=
cPos
t
.
update
(
np
.
float
(
str
(
'%8.1f'
%
(
cPos
/
1024
**
2
))))
cPos
=
cPos
+
ulDMALength
...
...
@@ -238,8 +237,8 @@ def evalMDH(mdh_blob, version):
mask
.
MDH_IMASCAN
-=
noImaScan
def
mapVBVD
(
filename
,
quiet
=
False
,
**
kwargs
):
def
mapVBVD
(
filename
,
quiet
=
False
,
**
kwargs
):
if
not
quiet
:
print
(
f
'pymapVBVD version
{
pkg
.
__version__
}
'
)
...
...
@@ -281,7 +280,7 @@ def mapVBVD(filename, quiet=False, **kwargs):
fid
.
seek
(
152
-
16
,
1
)
else
:
version
=
'vb'
version
=
'vb'
if
not
quiet
:
print
(
'Software version: VB'
)
...
...
@@ -342,7 +341,7 @@ def mapVBVD(filename, quiet=False, **kwargs):
# print(f'Scan {s + 1}/{NScans}, read all mdhs:')
mdh_blob
,
filePos
,
isEOF
=
loop_mdh_read
(
fid
,
version
,
NScans
,
s
,
measOffset
[
s
],
measLength
[
s
],
print_prog
=
not
quiet
)
# uint8; size: [ byteMDH Nmeas ]
measLength
[
s
],
print_prog
=
not
quiet
)
# uint8; size: [ byteMDH Nmeas ]
cPos
=
filePos
[
-
1
]
# filePos = filePos[:-1]
...
...
@@ -459,10 +458,10 @@ def mapVBVD(filename, quiet=False, **kwargs):
if
isCurrScan
.
any
():
currTwixObj
.
refscan_phasestab_ref1
.
readMDH
(
mdh
,
filePos
,
isCurrScan
)
else
:
currTwixObj
.
pop
(
'refscan_phasestab_ref1'
,
None
)
currTwixObj
.
pop
(
'refscan_phasestab_ref1'
,
None
)
if
isEOF
:
#recover from read error
#
recover from read error
for
keys
in
currTwixObj
:
if
keys
!=
'hdr'
:
currTwixObj
[
keys
].
tryAndFixLastMdh
()
...
...
@@ -470,24 +469,24 @@ def mapVBVD(filename, quiet=False, **kwargs):
for
keys
in
currTwixObj
:
if
keys
!=
'hdr'
:
currTwixObj
[
keys
].
clean
()
twix_obj
.
append
(
myAttrDict
(
currTwixObj
))
fid
.
close
()
if
len
(
twix_obj
)
==
1
:
twix_obj
=
twix_obj
[
0
]
# breakpoint()
return
twix_obj
return
twix_obj
# Add some class methods to AttrDict so that we get around the issue of not being able to
# access methods of objects accessed as attributes.
class
myAttrDict
(
AttrDict
):
def
__init__
(
self
,
*
args
):
def
__init__
(
self
,
*
args
):
super
().
__init__
(
*
args
)
def
search_header_for_keys
(
self
,
*
args
,
**
kwargs
):
def
search_header_for_keys
(
self
,
*
args
,
**
kwargs
):
"""Search header keys for terms.
Accesses search_for_keys method in header.
...
...
@@ -496,18 +495,18 @@ class myAttrDict(AttrDict):
regex (optional) : Search using regex or for exact strings.
top_lvl (optional) : Specify list of parameter sets to search (e.g. YAPS)
print_flag(optional): If False no output will be printed.
"""
return
self
[
'hdr'
].
search_for_keys
(
*
args
,
**
kwargs
)
"""
return
self
[
'hdr'
].
search_for_keys
(
*
args
,
**
kwargs
)
def
search_header_for_val
(
self
,
top_lvl
,
keys
,
**
kwargs
):
def
search_header_for_val
(
self
,
top_lvl
,
keys
,
**
kwargs
):
"""Return values for keys found using search terms for terms.
Args:
top_lvl : Specify list of parameter sets to search (e.g. YAPS)
keys : search terms as list of strings.
regex (optional): Search using regex or for exact strings.
"""
keys
=
self
[
'hdr'
].
search_for_keys
(
keys
,
print_flag
=
False
,
top_lvl
=
top_lvl
,
**
kwargs
)
"""
keys
=
self
[
'hdr'
].
search_for_keys
(
keys
,
print_flag
=
False
,
top_lvl
=
top_lvl
,
**
kwargs
)
out_vals
=
[]
for
key
in
keys
:
...
...
@@ -521,4 +520,3 @@ class myAttrDict(AttrDict):
MDH
=
list
(
self
.
keys
())
MDH
.
pop
(
MDH
.
index
(
'hdr'
))
return
MDH
mapVBVD/twix_map_obj.py
View file @
576f3ccf
...
...
@@ -6,6 +6,7 @@ import time
from
tqdm
import
tqdm
,
trange
import
logging
class
twix_map_obj
:
@
property
...
...
@@ -228,29 +229,30 @@ class twix_map_obj:
self
.
skipToFirstLine
=
False
else
:
self
.
skipToFirstLine
=
True
def
__str__
(
self
):
des_str
=
(
'***twix_map_obj***
\n
'
f
'File:
{
self
.
filename
}
\n
'
f
'Software:
{
self
.
softwareVersion
}
\n
'
f
'Number of acquisitions read
{
self
.
NAcq
}
\n
'
f
'Data size is
{
np
.
array2string
(
self
.
fullSize
,
formatter
=
{
"float"
:
lambda
x
:
"%.0f"
%
x
}
,
separator
=
","
)
}
\n
'
f
'Squeezed data size is
{
np
.
array2string
(
self
.
sqzSize
(),
formatter
=
{
"int"
:
lambda
x
:
"%i"
%
x
}
,
separator
=
","
)
}
(
{
self
.
sqzDims
()
}
)
\n
'
f
'NCol =
{
self
.
NCol
:
0.0
f
}
\n
'
f
'NCha =
{
self
.
NCha
:
0.0
f
}
\n
'
f
'NLin =
{
self
.
NLin
:
0.0
f
}
\n
'
f
'NAve =
{
self
.
NAve
:
0.0
f
}
\n
'
f
'NSli =
{
self
.
NSli
:
0.0
f
}
\n
'
f
'NPar =
{
self
.
NPar
:
0.0
f
}
\n
'
f
'NEco =
{
self
.
NEco
:
0.0
f
}
\n
'
f
'NPhs =
{
self
.
NPhs
:
0.0
f
}
\n
'
f
'NRep =
{
self
.
NRep
:
0.0
f
}
\n
'
f
'NSet =
{
self
.
NSet
:
0.0
f
}
\n
'
f
'NSeg =
{
self
.
NSeg
:
0.0
f
}
\n
'
f
'NIda =
{
self
.
NIda
:
0.0
f
}
\n
'
f
'NIdb =
{
self
.
NIdb
:
0.0
f
}
\n
'
f
'NIdc =
{
self
.
NIdc
:
0.0
f
}
\n
'
f
'NIdd =
{
self
.
NIdd
:
0.0
f
}
\n
'
f
'NIde =
{
self
.
NIde
:
0.0
f
}
'
)
f
'File:
{
self
.
filename
}
\n
'
f
'Software:
{
self
.
softwareVersion
}
\n
'
f
'Number of acquisitions read
{
self
.
NAcq
}
\n
'
f
'Data size is
{
np
.
array2string
(
self
.
fullSize
,
formatter
=
{
"float"
:
lambda
x
:
"%.0f"
%
x
}
,
separator
=
","
)
}
\n
'
f
'Squeezed data size is
{
np
.
array2string
(
self
.
sqzSize
(),
formatter
=
{
"int"
:
lambda
x
:
"%i"
%
x
}
,
separator
=
","
)
}
(
{
self
.
sqzDims
()
}
)
\n
'
f
'NCol =
{
self
.
NCol
:
0.0
f
}
\n
'
f
'NCha =
{
self
.
NCha
:
0.0
f
}
\n
'
f
'NLin =
{
self
.
NLin
:
0.0
f
}
\n
'
f
'NAve =
{
self
.
NAve
:
0.0
f
}
\n
'
f
'NSli =
{
self
.
NSli
:
0.0
f
}
\n
'
f
'NPar =
{
self
.
NPar
:
0.0
f
}
\n
'
f
'NEco =
{
self
.
NEco
:
0.0
f
}
\n
'
f
'NPhs =
{
self
.
NPhs
:
0.0
f
}
\n
'
f
'NRep =
{
self
.
NRep
:
0.0
f
}
\n
'
f
'NSet =
{
self
.
NSet
:
0.0
f
}
\n
'
f
'NSeg =
{
self
.
NSeg
:
0.0
f
}
\n
'
f
'NIda =
{
self
.
NIda
:
0.0
f
}
\n
'
f
'NIdb =
{
self
.
NIdb
:
0.0
f
}
\n
'
f
'NIdc =
{
self
.
NIdc
:
0.0
f
}
\n
'
f
'NIdd =
{
self
.
NIdd
:
0.0
f
}
\n
'
f
'NIde =
{
self
.
NIde
:
0.0
f
}
'
)
return
des_str
def
__repr__
(
self
):
...
...
@@ -313,10 +315,10 @@ class twix_map_obj:
isLastAcqGood
=
False
cnt
=
0
while
not
isLastAcqGood
and
self
.
NAcq
>
0
and
cnt
<
100
:
while
not
isLastAcqGood
and
self
.
NAcq
>
0
and
cnt
<
100
:
try
:
self
.
clean
()
self
.
unsorted
(
self
.
NAcq
)
self
.
unsorted
(
self
.
NAcq
)
isLastAcqGood
=
True
except
Exception
as
e
:
logging
.
exception
(
f
'An error occurred whilst trying to fix last MDH. NAcq =
{
self
.
NAcq
:
.
0
f
}
'
)
...
...
@@ -326,45 +328,45 @@ class twix_map_obj:
cnt
+=
1
def
clean
(
self
):
#Cut mdh data to actual size. Maybe we rejected acquisitions at the end
#due to read errors.
if
self
.
NAcq
==
0
:
#
Cut mdh data to actual size. Maybe we rejected acquisitions at the end
#
due to read errors.
if
self
.
NAcq
==
0
:
return
fields
=
[
'NCol'
,
'NCha'
,
'Lin'
,
'Par'
,
'Sli'
,
'Ave'
,
'Phs'
,
'Eco'
,
'Rep'
,
'Set'
,
'Seg'
,
'Ida'
,
'Idb'
,
'Idc'
,
'Idd'
,
'Ide'
,
'centerCol'
,
'centerLin'
,
'centerPar'
,
'cutOff'
,
'coilSelect'
,
'ROoffcenter'
,
'timeSinceRF'
,
'IsReflected'
,
'scancounter'
,
'timestamp'
,
'pmutime'
,
'IsRawDataCorrect'
,
'slicePos'
,
'iceParam'
,
'freeParam'
,
'memPos'
]
'centerCol'
,
'centerLin'
,
'centerPar'
,
'cutOff'
,
'coilSelect'
,
'ROoffcenter'
,
'timeSinceRF'
,
'IsReflected'
,
'scancounter'
,
'timestamp'
,
'pmutime'
,
'IsRawDataCorrect'
,
'slicePos'
,
'iceParam'
,
'freeParam'
,
'memPos'
]
nack
=
self
.
NAcq
idx
=
np
.
arange
(
0
,
nack
-
1
)
idx
=
np
.
arange
(
0
,
nack
-
1
)
for
f
in
fields
:
curr
=
getattr
(
self
,
f
)
if
curr
.
shape
[
0
]
>
nack
:
# rarely
curr
=
getattr
(
self
,
f
)
if
curr
.
shape
[
0
]
>
nack
:
# rarely
print
(
'Here'
)
setattr
(
self
,
f
,
curr
[
idx
])
# 1st dim: samples, 2nd dim acquisitions
self
.
NLin
=
np
.
max
(
self
.
Lin
)
+
1
#
+1 so that size isn't 0
self
.
NPar
=
np
.
max
(
self
.
Par
)
+
1
self
.
NSli
=
np
.
max
(
self
.
Sli
)
+
1
self
.
NAve
=
np
.
max
(
self
.
Ave
)
+
1
self
.
NPhs
=
np
.
max
(
self
.
Phs
)
+
1
self
.
NEco
=
np
.
max
(
self
.
Eco
)
+
1
self
.
NRep
=
np
.
max
(
self
.
Rep
)
+
1
self
.
NSet
=
np
.
max
(
self
.
Set
)
+
1
self
.
NSeg
=
np
.
max
(
self
.
Seg
)
+
1
self
.
NIda
=
np
.
max
(
self
.
Ida
)
+
1
self
.
NIdb
=
np
.
max
(
self
.
Idb
)
+
1
self
.
NIdc
=
np
.
max
(
self
.
Idc
)
+
1
self
.
NIdd
=
np
.
max
(
self
.
Idd
)
+
1
self
.
NIde
=
np
.
max
(
self
.
Ide
)
+
1
#ok, let us assume for now that all NCol and NCha entries are
#the same for all mdhs:
setattr
(
self
,
f
,
curr
[
idx
])
# 1st dim: samples, 2nd dim acquisitions
self
.
NLin
=
np
.
max
(
self
.
Lin
)
+
1
#
+1 so that size isn't 0
self
.
NPar
=
np
.
max
(
self
.
Par
)
+
1
self
.
NSli
=
np
.
max
(
self
.
Sli
)
+
1
self
.
NAve
=
np
.
max
(
self
.
Ave
)
+
1
self
.
NPhs
=
np
.
max
(
self
.
Phs
)
+
1
self
.
NEco
=
np
.
max
(
self
.
Eco
)
+
1
self
.
NRep
=
np
.
max
(
self
.
Rep
)
+
1
self
.
NSet
=
np
.
max
(
self
.
Set
)
+
1
self
.
NSeg
=
np
.
max
(
self
.
Seg
)
+
1
self
.
NIda
=
np
.
max
(
self
.
Ida
)
+
1
self
.
NIdb
=
np
.
max
(
self
.
Idb
)
+
1
self
.
NIdc
=
np
.
max
(
self
.
Idc
)
+
1
self
.
NIdd
=
np
.
max
(
self
.
Idd
)
+
1
self
.
NIde
=
np
.
max
(
self
.
Ide
)
+
1
#
ok, let us assume for now that all NCol and NCha entries are
#
the same for all mdhs:
# WTC not sure if this is a good idea - will keep the same as original for now
if
self
.
NCol
.
ndim
>
0
:
...
...
@@ -459,7 +461,7 @@ class twix_map_obj:
outSize
[
k
]
=
selRange
[
cDim
].
size
for
r
,
s
in
zip
(
selRange
,
self
.
dataSize
()):
for
r
,
s
in
zip
(
selRange
,
self
.
dataSize
()):
if
np
.
max
(
r
)
>
s
:
raise
Exception
(
'selection out of range'
)
# To implement indexing
...
...
@@ -504,7 +506,7 @@ class twix_map_obj:
def
unsorted
(
self
,
ival
=
None
):
# returns the unsorted data [NCol,NCha,#samples in acq. order]
if
ival
:
mem
=
np
.
atleast_1d
(
self
.
memPos
[
ival
-
1
])
mem
=
np
.
atleast_1d
(
self
.
memPos
[
ival
-
1
])
else
:
mem
=
self
.
memPos
out
=
self
.
readData
(
mem
)
...
...
@@ -622,27 +624,27 @@ class twix_map_obj:
fid
=
open
(
self
.
filename
,
'rb'
)
return
fid
def
readData
(
self
,
mem
,
cIxToTarg
=
None
,
cIxToRaw
=
None
,
selRange
=
None
,
selRangeSz
=
None
,
outSize
=
None
):
def
readData
(
self
,
mem
,
cIxToTarg
=
None
,
cIxToRaw
=
None
,
selRange
=
None
,
selRangeSz
=
None
,
outSize
=
None
):
mem
=
mem
.
astype
(
int
)
if
outSize
is
None
:
if
selRange
is
None
:
selRange
=
[
np
.
arange
(
0
,
self
.
dataSize
()[
0
]).
astype
(
int
),
np
.
arange
(
0
,
self
.
dataSize
()[
1
]).
astype
(
int
)]
#[slice(None,None,None),slice(None,None,None)]
selRange
=
[
np
.
arange
(
0
,
self
.
dataSize
()[
0
]).
astype
(
int
),
np
.
arange
(
0
,
self
.
dataSize
()[
1
]).
astype
(
int
)]
# [slice(None,None,None),slice(None,None,None)]
else
:
selRange
[
0
]
=
np
.
arange
(
0
,
self
.
dataSize
()[
0
]).
astype
(
int
)
#
slice(None,None,None)
selRange
[
1
]
=
np
.
arange
(
0
,
self
.
dataSize
()[
0
]).
astype
(
int
)
#
slice(None,None,None)
outSize
=
np
.
append
(
self
.
dataSize
()[
0
:
2
],
mem
.
size
).
astype
(
int
)
selRange
[
0
]
=
np
.
arange
(
0
,
self
.
dataSize
()[
0
]).
astype
(
int
)
#
slice(None,None,None)
selRange
[
1
]
=
np
.
arange
(
0
,
self
.
dataSize
()[
0
]).
astype
(
int
)
#
slice(None,None,None)
outSize
=
np
.
append
(
self
.
dataSize
()[
0
:
2
],
mem
.
size
).
astype
(
int
)
selRangeSz
=
outSize
cIxToTarg
=
np
.
arange
(
0
,
selRangeSz
[
2
])
cIxToRaw
=
cIxToTarg
cIxToTarg
=
np
.
arange
(
0
,
selRangeSz
[
2
])
cIxToRaw
=
cIxToTarg
# else:
# if np.array_equiv(selRange[0],np.arange(0,self.dataSize()[0]).astype(int)):
# selRange[0] = slice(None,None,None)
# if np.array_equiv(selRange[1],np.arange(0,self.dataSize()[1]).astype(int)):
# selRange[1] = slice(None,None,None)
out
=
np
.
zeros
(
outSize
,
dtype
=
np
.
csingle
)
out
=
out
.
reshape
((
selRangeSz
[
0
],
selRangeSz
[
1
],
-
1
))
...
...
@@ -653,7 +655,7 @@ class twix_map_obj:
readSize
=
self
.
freadInfo
.
sz
.
astype
(
int
)
readShape
=
self
.
freadInfo
.
shape
.
astype
(
int
)
readCut
=
self
.
freadInfo
.
cut
.
astype
(
int
)
keepOS
=
np
.
concatenate
([
list
(
range
(
int
(
self
.
NCol
/
4
))),
list
(
range
(
int
(
self
.
NCol
*
3
/
4
),
int
(
self
.
NCol
)))])
keepOS
=
np
.
concatenate
([
list
(
range
(
int
(
self
.
NCol
/
4
))),
list
(
range
(
int
(
self
.
NCol
*
3
/
4
),
int
(
self
.
NCol
)))])
bIsReflected
=
self
.
IsReflected
[
cIxToRaw
]
bRegrid
=
self
.
regrid
and
self
.
rampSampTrj
.
size
>
1
...
...
@@ -772,7 +774,8 @@ class twix_map_obj:
x
,
y
=
np
.
meshgrid
(
src_grid
[
1
],
src_grid
[
0
])
# NOTE: there is some minor differences in regridding precision between python and matlab, don't
# expect the same result from regridding
block
=
np
.
reshape
(
griddata
((
x
.
ravel
(),
y
.
ravel
()),
z
.
ravel
(),
(
xi
,
yi
),
method
=
'cubic'
),
sz
,
order
=
'F'
)
block
=
np
.
reshape
(
griddata
((
x
.
ravel
(),
y
.
ravel
()),
z
.
ravel
(),
(
xi
,
yi
),
method
=
'cubic'
),
sz
,
order
=
'F'
)
if
self
.
removeOS
:
block
=
np
.
fft
.
fft
(
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment