-
Notifications
You must be signed in to change notification settings - Fork 267
Miscellaneous MINC reader fixes #493
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1c4ac28
f545e33
a58ee03
1fc32c3
4aba3d8
e890e3e
8ea59d6
2e22508
04cd833
3974afa
9501c09
6cfad47
77cf9bb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -210,6 +210,14 @@ def __init__(self, filename, mode='r', mmap=None, version=1): | |
self.fp = open(self.filename, '%sb' % mode) | ||
if mmap is None: | ||
mmap = True | ||
try: | ||
self.fp.seek(0, 2) | ||
except ValueError: | ||
self.file_bytes = -1 # Unknown file length (gzip). | ||
else: | ||
self.file_bytes = self.fp.tell() | ||
self.fp.seek(0) | ||
|
||
self.use_mmap = mmap | ||
self.version_byte = version | ||
|
||
|
@@ -599,14 +607,22 @@ def _read_var_array(self): | |
else: # not a record variable | ||
# Calculate size to avoid problems with vsize (above) | ||
a_size = reduce(mul, shape, 1) * size | ||
if self.use_mmap: | ||
if self.file_bytes >= 0 and begin_ + a_size > self.file_bytes: | ||
data = fromstring(b'\x00'*a_size, dtype=dtype_) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Spaces around the |
||
elif self.use_mmap: | ||
mm = mmap(self.fp.fileno(), begin_+a_size, access=ACCESS_READ) | ||
data = ndarray.__new__(ndarray, shape, dtype=dtype_, | ||
buffer=mm, offset=begin_, order=0) | ||
else: | ||
pos = self.fp.tell() | ||
self.fp.seek(begin_) | ||
data = fromstring(self.fp.read(a_size), dtype=dtype_) | ||
# Try to read file, which may fail because the data is | ||
# at or past the end of file. In that case, we treat | ||
# this data as zeros. | ||
buf = self.fp.read(a_size) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comment here? I guess this is for a broken file where there's an expected variable truncated at the end? Do you really want to allow that case without raising an error? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, this error is absolutely "normal" in the sense that I routinely see files that have this condition. |
||
if len(buf) < a_size: | ||
buf = b'\x00'*a_size | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Spaces around the |
||
data = fromstring(buf, dtype=dtype_) | ||
data.shape = shape | ||
self.fp.seek(pos) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,7 +77,10 @@ def _get_dimensions(self, var): | |
dimorder = var.attrs['dimorder'].decode() | ||
except KeyError: # No specified dimensions | ||
return [] | ||
return dimorder.split(',') | ||
# The dimension name list must contain only as many entries | ||
# as the variable has dimensions. This reduces errors when an | ||
# unnecessary dimorder attribute is left behind. | ||
return dimorder.split(',')[:len(var.shape)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you give an example of a failure here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll check in a test case. Some MINC files contain stray "dimorder" attributes that are longer than the variable itself, e.g. a file may have a scalar image-min with a dimorder=zspace attribute. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test case would be good. Could you add a comment explaining as well? Otherwise it might be puzzling for someone coming fresh to the code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The MINC 2 format file I added to the test cases will exercise this. |
||
|
||
def get_data_dtype(self): | ||
return self._image.dtype | ||
|
@@ -95,7 +98,7 @@ def _get_valid_range(self): | |
info = np.iinfo(ddt.type) | ||
try: | ||
valid_range = self._image.attrs['valid_range'] | ||
except AttributeError: | ||
except (AttributeError, KeyError): | ||
valid_range = [info.min, info.max] | ||
else: | ||
if valid_range[0] < info.min or valid_range[1] > info.max: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the ValueError comes here? Best to isolate that line with
try
, as in: