Skip to content
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

WIP : ugly hack to fix the read_annot when parcellation has missing values #194

Merged
merged 1 commit into from Aug 30, 2013

Conversation

agramfort
Copy link
Contributor

the issue comes with annot that have missing values ie that don't cover the entire cortex. One issue I don't know how to address it that there is no np.nan for integers and we index at 0 for indexing with colortab output.

any hint welcome

addresses #189

cc @mwaskom

@matthew-brett
Copy link
Member

Thanks for this. Can you think of a test?

@matthew-brett
Copy link
Member

Can the freesurfer guys give any comment on this one?

@mwaskom
Copy link
Member

mwaskom commented Aug 23, 2013

I guess this looks reasonable. I can't think of a clean way to handle it :/

@mwaskom
Copy link
Member

mwaskom commented Aug 23, 2013

Is it worth raising a warning here?

@mwaskom
Copy link
Member

mwaskom commented Aug 23, 2013

Also maybe add a boolean argument to the function to "fix" incomplete annotations (a default value of True is fine)? I could think of non-visualization cases where people will expect the output of the function to be exactly what was saved into the file.

@agramfort
Copy link
Contributor Author

I am -1 for the boolean argument. I've just updated the docstring that was
not up to date...

All the lines are covered by tests but It's hard to add a test as the
freesurfer recon only outputs full annots.
We would need to add sample files in the repo, which we don't do for this
part of the code.

I think we can live with it :)

On Fri, Aug 23, 2013 at 6:41 PM, Michael Waskom notifications@github.comwrote:

Also maybe add a boolean argument to the function to "fix" incomplete
annotations (a default value of True is fine)? I could think of
non-visualization cases where people will expect the output of the function
to be exactly what was saved into the file.


Reply to this email directly or view it on GitHubhttps://github.com//pull/194#issuecomment-23175637
.

@matthew-brett
Copy link
Member

How hard would it be to create a tiny sample file for testing?

@agramfort
Copy link
Contributor Author

the freesurfer module has no data for testing and the default freesurfer
does not provide such files. I can commit the file provided
'left_mc-z.negative.sig.ocn.annot" it's 82KB. If so should I put it in
freesurfer/tests/data ?

@matthew-brett
Copy link
Member

How about gzipping it down to 20K? We do that for the DICOM files, for example.

We can't easily write annot files I guess?

@agramfort
Copy link
Contributor Author

How about gzipping it down to 20K? We do that for the DICOM files, for
example.

does it mean my annot reader need to support .gz files? Can you give a
snippet.

We can't easily write annot files I guess?

Indeed. We don't have writers.

@matthew-brett
Copy link
Member

Well - you would need to support file objects...

Maybe that is a worthwhile change to read_annot? As in (top of function):

from nibabel.openers import Opener
with Opener(file_like) as fobj:

That way you get file-like objects as input for free...

@agramfort
Copy link
Contributor Author

ok I'll give it a try asap

@agramfort
Copy link
Contributor Author

should be good to go after some clarification from doug on the freesurfer ML

there was a real bug with orig_ids=False :-/

luckily pysurfer uses orig_ids=True...

I am now wondering if we should not deprecate orig_ids=False ...

cc @mwaskom

@agramfort
Copy link
Contributor Author

btw I forced push after squashing my commits

@matthew-brett
Copy link
Member

I don't understand the issues here :(

Are you now testing the orig_ids=False code path with 0s?

@agramfort
Copy link
Contributor Author

It turns out that the annot provided by freesurfer also has 0 values. Is was just unnoticed before ...

…g_ids=False.

Vertices with 0 label were randomly merged with the first entry in the colortable
@agramfort
Copy link
Contributor Author

see my last change in test (squashed)

@matthew-brett
Copy link
Member

Please forgive me - I must be confused. Am I right in thinking there are no extra tests for the orid_ids=False code path in this PR?

@agramfort
Copy link
Contributor Author

Try the test with master. It should fail

@matthew-brett
Copy link
Member

It does. I understand why now; you are testing the labels for orig_ids=False against the labels for orig_ids=True hence you are testing orig_ids=False.

Are you happy with this fix? What about deprecating orig_ids=False? It is OK that this is the default?

@mwaskom
Copy link
Member

mwaskom commented Aug 28, 2013

Sorry as I'm in New York on vacation I haven't had time to fully wrap my
head around this. But I think I remain in favor of orig_ids=False. The
Freesurfer annot format is a little weird in that the values given to each
region are related to the color in the lookup table (I believe the id is R

  • (G * 256) + (B * 256 ^ 2)). So you end up with these very large numbers
    that have no obvious correspondence to each other or anything else. The LUT
    is in the annotation file anyway, making the information redundant. I much
    prefer the obvious data representation of sequential numbers.

Is there a reason we can't make the undefined region NaN?

On Tue, Aug 27, 2013 at 6:20 PM, Matthew Brett notifications@github.comwrote:

It does. I understand why now; you are testing the labels for
orig_ids=False against the labels for orig_ids=True hence you are testing
orig_ids=False.

Are you happy with this fix? What about deprecating orig_ids=False? It is
OK that this is the default?


Reply to this email directly or view it on GitHubhttps://github.com//pull/194#issuecomment-23376012
.

@agramfort
Copy link
Contributor Author

Sorry as I'm in New York on vacation I haven't had time to fully wrap my
head around this. But I think I remain in favor of orig_ids=False. The
Freesurfer annot format is a little weird in that the values given to each
region are related to the color in the lookup table (I believe the id is R

  • (G * 256) + (B * 256 ^ 2)).

indeed

So you end up with these very large numbers
that have no obvious correspondence to each other or anything else. The LUT
is in the annotation file anyway, making the information redundant. I much
prefer the obvious data representation of sequential numbers.

fair enough. But we have now -1 in label which is not a valid index.
I can live with it though.

Is there a reason we can't make the undefined region NaN?

yes. NaN cannot be in an integer array such as label.

@mwaskom
Copy link
Member

mwaskom commented Aug 28, 2013

Sorry again, i'm probably missing something obvious, but do we do something
such that label has to be int typed? Would round floats not work?

On Wed, Aug 28, 2013 at 3:13 AM, Alexandre Gramfort <
notifications@github.com> wrote:

Sorry as I'm in New York on vacation I haven't had time to fully wrap my
head around this. But I think I remain in favor of orig_ids=False. The
Freesurfer annot format is a little weird in that the values given to
each
region are related to the color in the lookup table (I believe the id is
R

  • (G * 256) + (B * 256 ^ 2)).

indeed

So you end up with these very large numbers
that have no obvious correspondence to each other or anything else. The
LUT
is in the annotation file anyway, making the information redundant. I
much
prefer the obvious data representation of sequential numbers.

fair enough. But we have now -1 in label which is not a valid index.
I can live with it though.

Is there a reason we can't make the undefined region NaN?

yes. NaN cannot be in an integer array such as label.


Reply to this email directly or view it on GitHubhttps://github.com//pull/194#issuecomment-23395467
.

@agramfort
Copy link
Contributor Author

Sorry again, i'm probably missing something obvious, but do we do something
such that label has to be int typed? Would round floats not work?

it could but it's kind of ugly to store indices as floats

@matthew-brett
Copy link
Member

Sorry - closed by accident.

@agramfort
Copy link
Contributor Author

so? what's our status?

@mwaskom
Copy link
Member

mwaskom commented Aug 29, 2013

OK I think your point about float indices being janky is correct. I guess
it's not really our fault that the format spec is a little weird, and your
-1 solution seems sound.

So I am +1 on -1 :)

On Thu, Aug 29, 2013 at 2:39 AM, Alexandre Gramfort <
notifications@github.com> wrote:

so? what's our status?


Reply to this email directly or view it on GitHubhttps://github.com//pull/194#issuecomment-23470005
.

@agramfort
Copy link
Contributor Author

matthew feel free to merge if you approve

is there a place to mention bug fixes? release notes?

@matthew-brett
Copy link
Member

For bug fix mentions - can you add something to the Changelog about this? I make the release notes from the Changelog file.

@agramfort
Copy link
Contributor Author

I don't see any current devel section in changelog. can you take care of it?

note:

  • bug fix in freesurfer.read_annot with orig_ids=False when annot contains
    vertices with no label.

thanks

matthew-brett added a commit that referenced this pull request Aug 30, 2013
MRG : ugly hack to fix the read_annot when parcellation has missing values

The issue comes with annot that have missing values ie that don't cover the entire cortex.
@matthew-brett matthew-brett merged commit fd365c7 into nipy:master Aug 30, 2013
@sanadeem
Copy link

Hi

With this hack, I am getting a type error at the following line:

labels[mask] = ord[np.searchsorted(ctab[ord, -1], labels[mask])]

TypeError: array cannot be safely cast to required type

Thanks

@matthew-brett
Copy link
Member

Can you point us to an example file with which we can replicate the problem? Thanks for any help in debugging this.

@agramfort
Copy link
Contributor Author

hi,

do you get this with any annot? what numpy version are you using? if it's
for one annot can you share it?

A

On Thu, Sep 26, 2013 at 4:52 AM, sanadeem notifications@github.com wrote:

Hi

With this hack, I am getting a type error at the following line:

labels[mask] = ord[np.searchsorted(ctab[ord, -1], labels[mask])]

TypeError: array cannot be safely cast to required type

Thanks


Reply to this email directly or view it on GitHubhttps://github.com//pull/194#issuecomment-25140577
.

@agramfort
Copy link
Contributor Author

weird I do:

In [8]: import nibabel as nib
In [9]: import numpy as np
In [10]: np.version
Out[10]: '1.6.1'
In [11]: nib.freesurfer.read_annot('lh.aparc.annot')

and everything works fine. Can you debug in ipython to figure out the type
issue?

@sanadeem
Copy link

Apparently the error doesn't occur with numpy 1.7.1 and only occurs with the assignment operation of
labels[mask] = ord[np.searchso....] under numpy version 1.6.1. Once I updated to numpy 1.7.1, it worked fine.

@agramfort
Copy link
Contributor Author

good to know but we cannot forget this anyway. Could you find out what the
problem is with your numpy 1.6.1?

thanks

@matthew-brett
Copy link
Member

Interesting - in a numpy 1.6.0 virtualenv, I get this:

(np-1.6.0)[mb312@tom ~/dev_trees/nibabel (main-master)]$ python -c 'import nibabel.freesurfer.io as nfi; nfi.read_annot("lh.aparc.annot")'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "nibabel/freesurfer/io.py", line 185, in read_annot
    data = np.fromfile(fobj, dt, vnum * 2).reshape(vnum, 2)
ValueError: total size of new array must be unchanged

On my desktop machine running numpy 1.6.2 python 2.7, the same command gives:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "nibabel/freesurfer/io.py", line 185, in read_annot
    data = np.fromfile(fobj, dt, vnum * 2).reshape(vnum, 2)
MemoryError

@sanadeem
Copy link

Interesting. On another machine with a clean installation of nibabel, with numpy 1.6.2 and python 2.7,
I get a different error as that mentioned by Matthew. Let me look into this, further.

@sanadeem
Copy link

I found another weird thing. When everything is working fine, the last conditional statement doesn't seem to go through when orig_ids=False. I have verified this on three different machines.

@agramfort
Copy link
Contributor Author

I am sorry I cannot reproduce these failures :(

grlee77 pushed a commit to grlee77/nibabel that referenced this pull request Mar 15, 2016
MRG : ugly hack to fix the read_annot when parcellation has missing values

The issue comes with annot that have missing values ie that don't cover the entire cortex.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants