Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #164 +/- ##
==========================================
+ Coverage 88.20% 88.67% +0.47%
==========================================
Files 5 5
Lines 814 839 +25
Branches 107 108 +1
==========================================
+ Hits 718 744 +26
- Misses 56 57 +1
+ Partials 40 38 -2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@orbeckst pls check this kindly |
orbeckst
left a comment
There was a problem hiding this comment.
This is already looking pretty good. Please also add doc strings and update CHANGELOG. Will have a closer look once this is done. Thank you!
gridData/tests/test_dx.py
Outdated
|
|
||
| assert isinstance(dx_field, gridData.OpenDX.field) | ||
|
|
||
| assert any('test_density' and 'test_user' in str(c) for c in dx_field.comments) |
There was a problem hiding this comment.
This is a logic error. 'test_density' and 'test_user' in str(c) evaluates as 'test_user' in str(c) due to Python's and short-circuit semantics — 'test_density' is truthy (not None / empty string), so it's ignored. Should be:
assert any('test_density' in str(c) for c in dx_field.comments)
assert any('test_user' in str(c) for c in dx_field.comments)There was a problem hiding this comment.
Actually to get what you are doing there, you might need
assert any(('test_density' in str(c) and 'test_user' in str(c)) for c in dx_field.comments)If you need them both to be true for a single comment.
There was a problem hiding this comment.
assert any(('test_density' in str(c) and 'test_user' in str(c)) for c in dx_field.comments)
This is giving error -
> assert any(('test_density' in str(c) and 'test_user' in str(c)) for c in dx_field.comments)
E assert False
E + where False = any(<generator object test_dx_from_grid.<locals>.<genexpr> at 0x0000021CD04CF220>)
gridData\tests\test_dx.py:104: AssertionError
Either I can do them separately or I can do this -
assert any(('test_density' and 'test_user') in str(c) for c in dx_field.comments)
gridData/core.py
Outdated
|
|
||
| converter = { | ||
| 'MRC': mrc.MRC.from_grid, | ||
| 'VDB': None, |
There was a problem hiding this comment.
VDB is going to be implemented but it should be removed for now. Currently the self.converter[]() has potential to try and call None() so best to just not include until the VDB support is added (or add a guard for such in the later usage).
There was a problem hiding this comment.
You can comment out this line.
gridData/core.py
Outdated
| grid, edges = g.histogramdd() | ||
| self._load(grid=grid, edges=edges, metadata=self.metadata) | ||
|
|
||
| def convert_to(self, format_specifier, tolerance=None, **kwargs): |
There was a problem hiding this comment.
The tolerance is currently not used at all. Should be removed and left for the PR that introduces VDB.
gridData/mrc.py
Outdated
| if filename is not None: | ||
| self.read(filename, assume_volumetric=assume_volumetric) | ||
|
|
||
| @staticmethod |
There was a problem hiding this comment.
Should these be classmethods instead of staticmethods?
There was a problem hiding this comment.
In the issue it was staticmethod and it's fine for basic usage as well. But classmethod is more good, if somebody subclasses mrc/dx
Should I change it?
There was a problem hiding this comment.
I did't know any better ;-). After some reading I also recommend going with @classmethod — if we need to work with inheritance or use it from another classmethod then classmethod will work better.
orbeckst
left a comment
There was a problem hiding this comment.
Overall looking good but there are some necessary changes. In particular, the MRC.native should return a MrcFile.
Could you please also add a section to the gridData.core docs about using from_grid() and .native? Have a look at the issue text for #161 and you can probably copy and paste from there. We just want to document somewhere for users that this API exists.
CHANGELOG
Outdated
| * 1.1.1 | ||
|
|
||
| Fixes | ||
| Changes |
CHANGELOG
Outdated
| ??/??/???? orbeckst | ||
| ??/??/???? orbeckst, spyke7 | ||
|
|
||
| * 1.1.1 |
There was a problem hiding this comment.
Change to 1.2.0 (under semantic versioning, we must increase minor version for new features)
| grid : Grid | ||
| type : str, optional | ||
| typequote : str, optional |
There was a problem hiding this comment.
add minimal explanations (can copy from other docs)
gridData/OpenDX.py
Outdated
|
|
||
| @property | ||
| def native(self): | ||
| """Return native object""" |
There was a problem hiding this comment.
- Add a sentence "The "native" object is the :class:
gridData.OpenDX.fielditself." - add a
.. versionadded:: 1.2.0(with two blank lines above)
gridData/tests/test_dx.py
Outdated
| assert_equal(dx_field.components['data'].array, data) | ||
| assert_equal(dx_field.components['positions'].origin, g.origin) |
gridData/tests/test_dx.py
Outdated
| g = Grid(data, origin=[0, 0, 0], delta=[1, 1, 1]) | ||
|
|
||
| dx_field = gridData.OpenDX.field.from_grid(g) | ||
| assert dx_field.native is dx_field No newline at end of file |
There was a problem hiding this comment.
This checks that it's the same object. Add another assertion that checks the type explicitly
assert isinstance(dx_field.native, OpenDX.field)
gridData/tests/test_mrc.py
Outdated
|
|
||
| mrc_obj = mrc.MRC.from_grid(g) | ||
|
|
||
| assert mrc_obj.native is mrc_obj |
There was a problem hiding this comment.
Needs to change as the native object should be the mrcfile.MrcFile.
- check type
- check some values
gridData/tests/test_mrc.py
Outdated
|
|
||
| assert isinstance(mrc_obj, mrc.MRC) | ||
|
|
||
| assert_equal(mrc_obj.array, data) |
There was a problem hiding this comment.
Given that the data are integers, assert_equal is technically correct but for consistency and robustness, also use assert_allclose, please.
|
@orbeckst @BradyAJohnston what to do exactly for |
|
Good point, MrcFile is tied to a file on disk. We could simply link it to a tmp file or maybe it works with StringIO? Or pass a filename in |
inside write() the filename can be a BytesIO object, as So ig it will work Will also try the tempfile as well. |
|
I used the tempfile at last cause of an error while using BytesIO
|
|
@spyke7 thanks for doing the experiments. Could we use mrcfile.mrcinterpreter.MrcInterpreter (instead of |
orbeckst
left a comment
There was a problem hiding this comment.
Good that you got it to work! I would like to try and get MRC to work with a stream and avoid a temp file that is not cleaned up. Please see comments.
Tests need a bit more work and the coverage is also below threshold. Have a look at the coverage report to see which lines are not tested.
Good work!
gridData/mrc.py
Outdated
| fd, temp_path = tempfile.mkstemp(suffix=".mrc") | ||
|
|
||
| os.close(fd) | ||
| self.write(temp_path) | ||
|
|
||
| return mrcfile.open(temp_path) |
There was a problem hiding this comment.
This is a reasonable workaround but it's a bit clunky, we have to parse the data twice (once in write, then after open) and we leave a tempfile around that will fill up the disk.
A slightly better solution would be to self.write() to a buffer and then have mrcfile.mrcinterpreter.MrcInterpreter directly read the buffer. That at least avoids the file on disk issue.
If that works then perhaps we can move almost all code from write() into native and the write() would just write the internal stream buffer to a file and in this way we only parse the data once with mrcfile.
There was a problem hiding this comment.
Let's try at least the "slightly better" solution — if that works then we can use it for now.
There was a problem hiding this comment.
Thanks for the suggestions,
What I am doing is that inside of write I will check whether a stream is given or not and then inside it only, call the MrcInterpreter
| native_mrc = mrc_wrapper.native | ||
|
|
||
| assert isinstance(native_mrc, mrcfile.mrcfile.MrcFile) | ||
| np.testing.assert_allclose(native_mrc.data, data.T) |
There was a problem hiding this comment.
Why do we need to transpose data to make it agree?
There was a problem hiding this comment.
If I do the native test with np.ones and symmetric matrix, then it will be no problem whether I give data or data.T
In case of (3,4,5) if I don't take the transpose it is throwing an AssertionError
as (x,y,z) -> (z,y,x)
the error -
AssertionError:
E Not equal to tolerance rtol=1e-07, atol=0
E
E (shapes (5, 4, 3), (3, 4, 5) mismatch)
There was a problem hiding this comment.
dx is working fine with just checking with data, with non-symmetric and varying delta
There was a problem hiding this comment.
| assert mrc_obj.rank == 3 | ||
|
|
||
| def test_mrc_native_property(self): | ||
| data = np.ones((3, 3, 3)) |
There was a problem hiding this comment.
use a non-symmetric grid eg arange(60).reshape(3,4,5) ; with only ones you can miss issues with axes orientations.
|
|
||
| def test_mrc_native_property(self): | ||
| data = np.ones((3, 3, 3)) | ||
| g = Grid(data, origin=[0, 0, 0], delta=[1, 1, 1]) |
There was a problem hiding this comment.
Varydelta = [1., 3., 0.5]. Generally you want as little symmetry as possible so that you can catch errors that just transpose indices.
| err_msg="deltas of written grid do not match original") | ||
|
|
||
| def test_dx_from_grid(): | ||
| data = np.ones((5, 5, 5), dtype=np.float32) |
There was a problem hiding this comment.
use a non-symmetric grid eg arange(60).reshape(3,4,5)
| assert_allclose(dx_field.components['positions'].origin, g.origin) | ||
|
|
||
| def test_dx_native(): | ||
| data = np.ones((5, 5, 5)) |
There was a problem hiding this comment.
use a non-symmetric grid eg arange(60).reshape(3,4,5)
|
|
||
| def test_dx_native(): | ||
| data = np.ones((5, 5, 5)) | ||
| g = Grid(data, origin=[0, 0, 0], delta=[1, 1, 1]) |
| assert_allclose(grid.grid, ccp4data.array) | ||
|
|
||
| def test_mrc_from_grid(self): | ||
| data = np.arange(27, dtype=np.float32).reshape((3, 3, 3)) |
There was a problem hiding this comment.
even better: use a non-symmetric grid eg arange(60).reshape(3,4,5)
|
|
||
| def test_mrc_from_grid(self): | ||
| data = np.arange(27, dtype=np.float32).reshape((3, 3, 3)) | ||
| g = Grid(data, origin=[1.0, 2.0, 3.0], delta=[0.5, 0.5, 0.5]) |
There was a problem hiding this comment.
vary delta, e.g. [0.5, 1.5, 1.0]
|
Regarding coverage: Just check that the lines that you wrote get covered. You ran black on the whole file so this picks up any of those lines. You are not responsible for writing other tests if this was just a formatting change (this is one of the reasons why we normally do reformatting in separate PRs.) |
|
Looking at https://app.codecov.io/gh/MDAnalysis/GridDataFormats/pull/164 it seems that the |
Co-authored-by: Oliver Beckstein <orbeckst@gmail.com>
|
So, my plan is this -
problem is - There is no other way of writing a stream except the interpreter. It would be helpful if I get some info regarding the Mrcfile codebase @orbeckst @BradyAJohnston pls see once when you have got time |
- MRC.native generates a new mrcfile.mrcinterpreter.MrcInterpreter instance - use the MrcInterpreter instance for writing out Note: only uncompressed files currently supported.
|
I updated with how I think this could work ( |
This is regarding #161
Implemented from_grid() a static method and native (property) inside OpenDX.py and mrc.py