Opened 7 years ago

Closed 7 years ago

#1400 closed defect (fixed)

Volume.surface_level_for_enclosed_volume only correct for orthogonal cell angles

Reported by: Tristan Croll Owned by: Tom Goddard
Priority: moderate Milestone:
Component: Volume Data Version:
Keywords: Cc:
Blocked By: Blocking:
Notify when closed: Platform: all
Project: ChimeraX

Description

At the moment, Volume.surface_level_for_enclosed_volume() starts:

  def surface_level_for_enclosed_volume(self, volume, tolerance = 1e-3,
                                        max_bisections = 30, rank_method = False):

    sx,sy,sz = self.data.step
    cell_volume = float(sx)*sy*sz

That's only going to be correct if the cell angles are all 90 degrees. Probably won't make much difference in many cases, but there will be situations where it starts to deviate quite a lot from the true volume. I believe the following should cover any sane case (that is, where each voxel is still a parallelepiped):

def voxel_volume(volume):
    import numpy
    from math import sqrt
    a,b,c = v.data.step
    angles = numpy.radians(v.data.cell_angles)
    cos_alpha, cos_beta, cos_gamma = numpy.cos(angles)
    return a*b*c*sqrt(1-cos_alpha**2-cos_beta**2-cos_gamma**2
        + 2*cos_alpha*cos_beta*cos_gamma)

Would be even better for my purposes if this was implemented as a property of Volume.

Change History (2)

in reply to:  1 ; comment:1 by tic20@…, 7 years ago

... make that:

{{{
def voxel_volume(volume):
     import numpy
     from math import sqrt
     a,b,c = volume.data.step
     angles = numpy.radians(volume.data.cell_angles)
     cos_alpha, cos_beta, cos_gamma = numpy.cos(angles)
     return a*b*c*sqrt(1-cos_alpha**2-cos_beta**2-cos_gamma**2
         + 2*cos_alpha*cos_beta*cos_gamma)
}}}
Sorry about that.

On 2018-10-31 13:41, ChimeraX wrote:

comment:2 by Tom Goddard, 7 years ago

Resolution: fixed
Status: assignedclosed

Fixed.

I added a voxel_volume() method to Grid_Data (v.data.voxel_volume()) that correctly handles skewing. It uses the determinant of ijk_to_xyz_transform.

I also added "measure volume" and "measure area" commands for surfaces (to verify that the enclosedVolume option is working correctly on skewed data).

Note: See TracTickets for help on using tickets.