-
Notifications
You must be signed in to change notification settings - Fork 260
RF: Use XmlSerializable, XmlParser for Gifti load/save #365
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
… and attached to each XmlBasedImage subclass.
class GiftiImage(FileBasedImage, xml.XmlSerializable): | ||
class GiftiImage(xml.XmlBasedImage): | ||
""" | ||
The Gifti spec suggests using the following suffixes to your |
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.
Here, I moved the docstring from GiftiImage.to_file_map
to GiftiImage
, so that to_file_map
could be moved to XmlBasedImage
.
Checked off all items but one: not sure the best way to avoid the recursive imports here. Should be ready for a looksie anytime--I even tried scrubbing some of the old code :) |
@effigies I put
I think the object model and abstractions here are good; I'd like to keep them. But, since |
I suppose I'm inclined to not bother with |
@np.deprecate_with_doc("Use GiftiImageParser instead.") | ||
def __init__(self, *args, **kwargs): | ||
super(Outputter, self).__init__(*args, **kwargs) | ||
self.img = None |
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.
Outputter
had an initialize
method that should be preserved.
Sorry for the delay. This looks reasonable to me. The main design issue I see is still whether or not we want an I think I can go either way. If anybody else has strong opinions, I can probably be pushed to one side or the other. |
I would prefer to move the code back into |
That sounds good to me. |
@effigies I did as outlined above, and deprecated |
out.img.filename = fname | ||
return out.img | ||
def initialize(self, *args, **kwargs): | ||
self.__init__(*args, **kwargs) |
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.
Outputter.__init__
doesn't quite do the same thing as Outputter.initialize
, since it also calls super(GiftiImageParser, self).__init__
, which could change the buffer size and all that. I would just do the original contents, but short, like:
def initialize(self):
""" Initialize outputter
"""
self.fsm_state = []
self.nvpair = self.da = self.coordsys = self.lata = self.label = None
self.meta_global = self.meta_da = self.write_to = None
self._char_blocks = None
self.count_da = True
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.
Setting encoding
and buffer_size
is new. I figured since initialize
is deprecated, nobody will call it with those args, nor would those args be non-defaults. I'd prefer to keep the # of lines for deprecated functions minimal.
As a side note, I could remove the arguments from initialize
and __init__
to match the original definitions.
LMK what you think.
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 would keep the original prototypes and docstring on initialize
. But point taken on only defaults being used in any case, so revert the prototypes and I'm okay here.
Done. |
else: | ||
datasource = fptr | ||
class Outputter(GiftiImageParser): | ||
@np.deprecate_with_doc("Use GiftiImageParser instead.") |
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.
Should this deprecation be on the class instead of __init__
?
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 probably don't understand what deprecating the class would do; could you help make that clear to me?
In previous cases I remember deprecating __init__
so that the deprecation is lazy--it only triggers if someone instantiates the class, and not when the file is simply imported. That's the only goal here.
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 thought the @np.deprecate
functions modify documentation. Do they also raise warnings? If so, this makes sense.
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.
yep, they raise warnings--I add a deprecation warning test case each time we add this decorator, to make sure.
Okay, LGTM then. Anybody else have comments? |
Any chance we can merge this one? |
I think people have had a chance to voice objections. In it goes. |
RF: Use XmlSerializable, XmlParser for Gifti load/save
Yes, sorry I haven't had a chance to review. Next week is better for me, by Tuesday afternoon I will have more time. |
file_map=file_map) | ||
super(GiftiImage, self).__init__(header=header, extra=extra, | ||
file_map=file_map) | ||
# placed here temporarily for git diff purposes |
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.
Rewrite comment now you've decided in this implementation?
@matthew-brett Should I revert this merge? |
Oh - no - sorry - you did good to merge, thanks for doing it. I was only adding post-merge suggestions. Happy to do that as a PR if it's easier. |
RF: Use XmlSerializable, XmlParser for Gifti load/save
CiftiImage
(#249) andGiftiImage
share a lot of logic. Both have functions for parsing, both will use similar logic for loading and saving.XmlBasedImage
andXmlImageParser
encapsulates the shared code, and defines a (hopefully) clean object model for any future images that are defined in XML.XmlImageParser
- a new abstract class that does most of the work here. Defines a structure for parsing XML files; every xml-based image will have to define one, specific to that image format. This essentially generalizes the object model used inparse_gifti_fast.py
.XmlBasedImage
- a light wrapper aroundFileBasedImage
that calls into theXmlImageParser
for the image class on read, and takes care of small details onwrite
(call intoto_xml()
). New required class property:parser
(similar usage toheader
)Things done:
XmlImageParser
andXmlBasedImage
GiftiImage
to useXmlBasedImage
, andparse_gifti_fast
to useXmlImageParser
parse_gifti_file
and related objects.Things to do:
gifti.py
andparse_gifti_fast.py
; each refers to objects in the other. Perhaps we can simply combine them?parse_gifti_fast
tests to new object model.parse_gifti_file
buffer_size
passing vianibabel.load()
I'm pushing this PR out there now as (1) it seems to pass tests and (2) to get feedback on the object model / design as early in the development process as possible.
I'm not in a big rush on this; just wanted to get it out there while it was on my mind.