-
Notifications
You must be signed in to change notification settings - Fork 28
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
API: Datahandler now functions as a class #156
Conversation
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.
Changes requested. Main thing is I want to see the two DataHandler classes in the same file. When that's done, the unit tests should also be refactored into the same file. I think it would be better to use an abstract class, though this is not strictly necessary.
I've not read the notebook changes yet because they don't render on GitHub. Presumably the notebook changes are only to do with using a custom datahandler?
fissa/tests/test_datahandler.py
Outdated
from .. import roitools | ||
|
||
datahandler = DataHandler() |
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 don't like this. datahandler
is the name of the module and DataHandler
the name of the class. Should not make the name of the instance of DataHandler
clash with the name of the module. Need to use a different name for the instance, such as
datahandler = DataHandler() | |
dh = DataHandler() |
(which obviously has implications for later code in the file which needs datahandler changed to dh)
Maybe we should consider renaming the module instead though.
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've not read the notebook changes yet because they don't render on GitHub. Presumably the notebook changes are only to do with using a custom datahandler?
Yes. With an explanation of how to use it.
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.
Maybe we should consider renaming the module instead though.
The case ofdatahandler = DataHandler()
is actually consistent with how use core.Experiment() class (we call exp=fissa.Experiment() or experiment=fissa.Experiment() a few times in the examples). But I agree it is not the best naming. Now I import DataHandler from datahandler, and then make an DataHandler object called datahandler. Yuk.
We could rename the module to extraction
(following Suite2p) and keep the class-name, as well as use your dh
suggestion, so it becomes
datahandler = DataHandler() | |
from ..extraction import DataHandler() | |
dh = DataHandler() |
from .. import roitools | ||
|
||
datahandler = DataHandler() |
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.
As for the other file.
fissa/datahandler_framebyframe.py
Outdated
|
||
|
||
def image2array(image): | ||
"""Open a given image file as a PIL.Image instance. | ||
class DataHandler(datahandler.DataHandler): |
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.
Great to see this being done as a subclass. But I'd actually like to see the two data handlers put in the same file.
class DataHandler():
# existing code as in other file
class DataHandlerFrameByFrame(DataHandler):
# code as you have in this file
That would be much tidier. Also, you've got this weird thing at the moment where you can do
import datahandler_framebyframe
x = datahandler_framebyframe.DataHandler()
y = datahandler_framebyframe.datahandler.DataHandler()
x.__class__ == y.__class__ # Returns False and x and y have different behaviours
# Not behaviour that a user of this API would expect.
Also, I think it might be better coding practice to use an abstract class (DataHandlerAbstract
) and have both DataHandler
and DataHandlerFrameByFrame
inherit from the abstract class instead of having DataHandlerFrameByFrame
inherit from DataHandler
. Because they are more like siblings than parent/child. Also then we expect custom made data handler objects to inherit from DataHandlerAbstract
, but they don't have to inherit from DataHandler
.
You should write DataHandlerAbstract
to have all the methods used it DataHandler
defined as raise NotImplementedError()
. Any methods which are common to all data handlers can be implemented for real and then the children don't have to overwrite those methods.
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.
Agreed. Then we can also merge the datahandler test files.
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.
About an abstract class -- I will implement it (and it will have only NotImplementedErrors
, because all the functions are different for framebyframe!), but might not use it in the tutorial. It makes a lot more sense for most users to only edit one or two of the functions used in the standard DataHandler. I'll just make a comment for advanced users that they can define an entirely new handler from DataHandlerAbstract.
Also, commit f9efaff is off-topic and should be in a different PR concerning verbosity changes. Sorry I missed that before! |
Actually it does fit here because it fixes an error I introduced myself earlier in this PR.>.> |
Oh, I see. I missed it because it's not part of the PR's diff. Could you rebase and squash f9efaff into the commit that did the thing that it is undoing? |
I updated this PR. The datahandler module has been renamed to the extraction module. In the end I opted for Some possibilities
|
Aha! I can also rename the current |
This is now done. I'm happy with this to be merged into master and then we can do the other PRs. |
This involves quite a lot of changes. This is classed as an API change as anyone using custom dataloaders in our previous way will either have to stay with an older version of FISSA, or migrate their datahandlers to this new method. I will describe this in detail in the tutorial notebook that is to follow in another commit.
fb0cc12
to
a1d0c45
Compare
a1d0c45
to
f55c8f7
Compare
fissa/tests/test_core.py
Outdated
self.datahandler = DataHandlerTifffile() | ||
|
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.
This isn't something that's a common dependency across tests, so it should not be defined here. If there's something wrong with this line of code, it should only be breaking the one or two tests that use a datahandler and not every test that's part of this class.
self.datahandler = DataHandlerTifffile() |
fissa/tests/test_extraction.py
Outdated
self.assert_equal(actual, self.expected) | ||
|
||
|
||
class TestRois2Masks(BaseTestCase): |
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.
class TestRois2Masks(BaseTestCase): | |
class TestRois2MasksTifffile(BaseTestCase): |
fissa/tests/test_extraction.py
Outdated
from ..extraction import DataHandlerTifffile, DataHandlerPillow | ||
from .. import roitools | ||
|
||
class TestImage2Array(BaseTestCase): |
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.
Need to stop these classes colliding with the same name!
class TestImage2Array(BaseTestCase): | |
class TestImage2ArrayTifffile(BaseTestCase): |
fissa/tests/test_extraction.py
Outdated
os.remove('test.tif') | ||
|
||
|
||
class TestRois2Masks(BaseTestCase): |
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.
class TestRois2Masks(BaseTestCase): | |
class TestRois2MasksPillow(BaseTestCase): |
fissa/tests/test_extraction.py
Outdated
self.datahandler.rois2masks(polys3d, self.data) | ||
|
||
|
||
class TestImage2Array(BaseTestCase): |
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.
class TestImage2Array(BaseTestCase): | |
class TestImage2ArrayPillow(BaseTestCase): |
Co-authored-by: Scott Lowe <[email protected]>
…ahandler loading Co-authored-by: Scott Lowe <[email protected]>
Co-authored-by: Scott Lowe <[email protected]>
Co-authored-by: Scott Lowe <[email protected]>
Co-authored-by: Scott Lowe <[email protected]>
Co-authored-by: Scott Lowe <[email protected]>
Co-authored-by: Scott Lowe <[email protected]>
Co-authored-by: Scott Lowe <[email protected]>
7f5a4bf
to
4e952e0
Compare
Codecov Report
@@ Coverage Diff @@
## master #156 +/- ##
==========================================
+ Coverage 92.68% 92.97% +0.28%
==========================================
Files 9 8 -1
Lines 779 811 +32
Branches 158 161 +3
==========================================
+ Hits 722 754 +32
Misses 29 29
Partials 28 28
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
This involves quite a lot of changes.
This is classed as an API change as anyone using custom dataloaders in
our previous way will either have to stay with an older version of
FISSA, or migrate their datahandlers to this new method.
The tutorial notebook now extensively explains this at the end.
Another important change this brings is that for multiprocessing the datahandler class instance is now passed into the function for multiprocessing instead of defined as a global library, which will help with solving #147.