-
Notifications
You must be signed in to change notification settings - Fork 261
BF: deterministic order of slice_time deduction, warning if multiple match #647
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
Conversation
hm, appveyor failures on python 3.5 seems to not be related |
Would you mind adding a test that triggers the failure? |
Codecov Report
@@ Coverage Diff @@
## master #647 +/- ##
==========================================
+ Coverage 88.81% 88.82% +<.01%
==========================================
Files 92 92
Lines 11278 11285 +7
Branches 1848 1850 +2
==========================================
+ Hits 10017 10024 +7
Misses 926 926
Partials 335 335
Continue to review full report at Codecov.
|
…ultiple available
ae2f946
to
244c8cf
Compare
added some basic test for guaranteeing that it is always the same, see 244c8cf (although I didn't check if it would be triggered without the fix, I assume it might/would though ;-)) |
@matthew-brett @effigies - but what do you think in general, either my solution would suffice or it should be more thorough, e.g. relying on the original order of those labels in the structure? we better fix it once instead of making output inconsistent across versions if we keep fixing it up incrementally ;-) |
My inclination would be to set a canonical ordering, rather than depend on sorting by name, and insertion order is the most intuitive way to impose this order. This preference is due to the general move in Python to ordered dictionaries, as well as lexicographical order being an artificial (and potentially annoying) constraint. Not a strongly-held opinion though. Happy to be argued out. |
nibabel/tests/test_nifti1.py
Outdated
hdr2.set_dim_info(slice=2) | ||
hdr2.set_slice_duration(0.1) | ||
hdr2.set_data_shape((1, 1, 2)) | ||
hdr2.set_slice_times([0.1, 0]) # will generate warning that multiple match |
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.
Want to check that the warning is generated? e.g.
with clear_and_catch_warnings() as w:
hdr2.set_slice_times([0.1, 0])
assert len(w) == 1
Thank you @effigies ! Do you see an easy generic way to make those Recorders to use ordered dict without duplicating storage etc? |
I see a couple options:
nibabel/nibabel/volumeutils.py Line 81 in 2a127cc
Lines 143 to 150 in 2a127cc
Becomes: slice_order_codes = Recoder(( # code, label
(0, 'unknown'),
(1, 'sequential increasing', 'seq inc'),
(2, 'sequential decreasing', 'seq dec'),
(3, 'alternating increasing', 'alt inc'),
(4, 'alternating decreasing', 'alt dec'),
(5, 'alternating increasing 2', 'alt inc 2'),
(6, 'alternating decreasing 2', 'alt dec 2')),
fields=('code', 'label'), map_maker=OrderedDict) Not sure if this resolves your duplicated storage concern, as I'm not quite sure what that concern is. These seem like pretty small dictionaries, anyway. |
This should allow for consistent ordering of items in the Recoder
Thank you @effigies ! went 1. route, had to add OrderedSet construct, seems to work and IMHO should be "better" ;-) Hopefully noone relied on doctesting output to be a |
Pre-release tests are seg-faulting, but otherwise this LGTM. |
May be getting bitten by OpenMathLib/OpenBLAS#1641. May be worth reporting upstream, probably numpy, but I haven't dug any further yet. |
It seems that in numpy/numpy#11551 there were OpenBLAS-based build issues, but it was decided that this wasn't something that could be fixed in numpy, is that right @matthew-brett? I'm inclined to go ahead and merge, and accept failing |
Okay, looks like the broken wheels were rebuilt. I'm 👍 for merge. @matthew-brett, any further comments? |
Thanks @yarikoptic. |
Initially hit while trying to make dcmstack python3 compatible: moloney/dcmstack#61
What I found that dcmstack test fails due to slice_order not matching original one (4) on some runs under Python 3. But the issue is generic -- reliance on order of keys in dict, and ignoring possible multiple "matches". It was triggered by dcmstack since its test image just has 2 slices so multiple slice orders would match.
I've looked into the logic in nibabel, and my proposed solution is just a solution:
Recoder
class which stores those mappings starts to use OrderedDict to maintain order in which choices are specified, and then code should explore in that order. I was scared to touchRecorder
class since it relies onself.__dict__
assignmentsI would be interested to hear what others think about this issue, and how likely it affected anyone's real data