Skip to content

Commit

Permalink
correctly reorient and center coordinates from MRC
Browse files Browse the repository at this point in the history
- fix #76
- add tests
  • Loading branch information
orbeckst committed Feb 19, 2022
1 parent 933cf9d commit a6b2519
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 5 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ The rules for this file:
* use mrcfile library to parse MRC files (including CCP4) using the
new mrc.MRC class (issue #83)

Fixes

* The new mrc module correctly reorients the coordinate system based
on mapc, mapr, maps and correctly calculates the origin (issue #76)

Deprecations

* The CCP4 module (replaced by mrc) will be removed in 0.8.0.
Expand Down
15 changes: 11 additions & 4 deletions gridData/mrc.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,18 @@ def read(self, filename):
# by sorting mapc, mapr, maps in ascending order, i.e., to obtain x,y,z.
# mrcfile provides the data in zyx shape (without regard to map*) so we first
# transpose it to xyz and then reorient with axes_c_order.
axes_order = np.hstack([mrc.header.mapc, mrc.header.mapr, mrc.header.maps])
#
# All other "xyz" quantitities are also reordered.
axes_order = np.hstack([h.mapc, h.mapr, h.maps])
axes_c_order = np.argsort(axes_order)
self.array = np.transpose(np.transpose(mrc.data), axes=axes_c_order)
self.delta = np.diag([mrc.voxel_size.x, mrc.voxel_size.y, mrc.voxel_size.z])
self.origin = np.array([h.origin.x, h.origin.y, h.origin.z])
self.delta = np.diag(
np.array([mrc.voxel_size.x, mrc.voxel_size.y, mrc.voxel_size.z])[axes_c_order])
# the grid is shifted to the CCP4 origin by offset
# (assume orthorhombic)
offsets = np.hstack([h.nxstart, h.nystart, h.nzstart])[axes_c_order] * np.diag(self.delta)
# GridData origin is centre of cell at x=col=0, y=row=0 z=seg=0
self.origin = np.hstack([h.origin.x, h.origin.y, h.origin.z])[axes_c_order] + offsets
self.rank = 3

@property
Expand All @@ -127,7 +134,7 @@ def shape(self):

@property
def edges(self):
"""Edges of the grid cells, origin at centre of 0,0,..,0 grid cell.
"""Edges of the grid cells, origin at centre of 0,0,0 grid cell.
Only works for regular, orthonormal grids.
"""
Expand Down
15 changes: 14 additions & 1 deletion gridData/tests/test_mrc.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,20 @@ def test_axes_orientation(ccp4data):
# correctly interpret mapc, mapr, maps = 2, 1, 3
# for nx, ny, nz = 96, 76, 70.
# see also #76
assert_equal(ccp4data.array.shape, (76, 96, 70))
assert_equal(ccp4data.shape, (76, 96, 70))

def test_delta(ccp4data):
assert_almost_equal(ccp4data.delta, np.array(
[[0.5452381, 0. , 0. ],
[0. , 0.5452381, 0. ],
[0. , 0. , 0.5603125]], dtype=np.float32))

def test_origin(ccp4data):
# shift with nxstart, nystart, nzstart and delta
#
# (visual comparison of CCP4 and DX file in ChimeraX at same
# level shows full agreement)
assert_almost_equal(ccp4data.origin, [-12.5404758, -2.1809523, 57.151876 ])

def test_triclinic_ValueError():
with pytest.raises(ValueError,
Expand Down

0 comments on commit a6b2519

Please sign in to comment.