from __future__ import division
import logging
import numpy as np
from .unionize_record import Unionize
[docs]class TissuecyteBaseUnionize(Unionize):
__slots__ = ['sum_pixels', 'sum_projection_pixels', 'sum_projection_pixel_intensity',
'max_voxel_index', 'max_voxel_density', 'projection_density',
'projection_energy', 'projection_intensity', 'direct_sum_projection_pixels',
'sum_pixel_intensity']
def __init__(self):
'''A unionize record summarizing observations from a tissuecyte
projection experiment
'''
for key in self.__slots__:
setattr(self, key, 0)
[docs] def propagate(self, ancestor, copy_all=False):
'''Update a rootward unionize with data from this unionize record
Parameters
----------
ancestor : TissuecyteBaseUnionize
will be updated
Returns
-------
ancestor : TissuecyteBaseUnionize
'''
ancestor.sum_pixels += self.sum_pixels
ancestor.sum_projection_pixels += self.sum_projection_pixels
ancestor.sum_projection_pixel_intensity += self.sum_projection_pixel_intensity
ancestor.sum_pixel_intensity += self.sum_pixel_intensity
if ancestor.max_voxel_density <= self.max_voxel_density:
ancestor.max_voxel_density = self.max_voxel_density
ancestor.max_voxel_index = self.max_voxel_index
if copy_all:
ancestor.direct_sum_projection_pixels += self.direct_sum_projection_pixels
return ancestor
[docs] def set_max_voxel(self, density_array, low):
'''Find the voxel of greatest density in this unionizes spatial domain
Parameters
----------
density_array : ndarray
Float values are densities per voxel
low : int
index in full flattened, sorted array of starting voxel
'''
if self.sum_projection_pixels > 0:
self.max_voxel_index = np.argmax(density_array)
self.max_voxel_density = density_array[self.max_voxel_index]
self.max_voxel_index += low
[docs] def output(self, output_spacing_iso, volume_scale, target_shape, sort):
'''Generate derived data for this unionize
Parameters
----------
output_spacing_iso : numeric
Isometric spacing of reference space in microns
volume_scale : numeric
Scale factor mapping pixels to microns^3
target_shape : array-like of numeric
Shape of reference space
'''
if self.sum_pixels > 0:
self.projection_density = self.sum_projection_pixels / self.sum_pixels
self.projection_energy = self.sum_projection_pixel_intensity / self.sum_pixels
if self.sum_projection_pixels > 0:
self.projection_intensity = self.sum_projection_pixel_intensity / self.sum_projection_pixels
output = {k: getattr(self, k) for k in self.__slots__}
output['volume'] = self.sum_pixels * volume_scale
output['direct_projection_volume'] = self.direct_sum_projection_pixels * volume_scale
output['projection_volume'] = self.sum_projection_pixels * volume_scale
output['sum_pixel_intensity'] = self.sum_pixel_intensity
if self.max_voxel_index > 0:
self.max_voxel_index = sort[self.max_voxel_index]
mv_pos = np.unravel_index([self.max_voxel_index], dims=target_shape, order='C')
if len(mv_pos[0]) == 0:
mv_pos = [[0], [0], [0]]
else:
mv_pos = [[0], [0], [0]]
output['max_voxel_x'] = mv_pos[0][0] * output_spacing_iso
output['max_voxel_y'] = mv_pos[1][0] * output_spacing_iso
output['max_voxel_z'] = mv_pos[2][0] * output_spacing_iso
del output['max_voxel_index']
return output
[docs]class TissuecyteInjectionUnionize(TissuecyteBaseUnionize):
[docs] def calculate(self, low, high, data_arrays):
data_arrays = self.slice_arrays(low, high, data_arrays)
self.sum_pixels = np.multiply(data_arrays['sum_pixels'], data_arrays['injection_fraction']).sum()
self.sum_projection_pixels = np.multiply(data_arrays['sum_pixels'], data_arrays['injection_density']).sum()
self.direct_sum_projection_pixels = self.sum_projection_pixels
self.sum_projection_pixel_intensity = np.multiply(data_arrays['sum_pixels'], data_arrays['injection_energy']).sum()
self.sum_pixel_intensity = data_arrays['injection_sum_pixel_intensities'].sum()
self.set_max_voxel(data_arrays['injection_density'], low)
[docs]class TissuecyteProjectionUnionize(TissuecyteBaseUnionize):
[docs] def calculate(self, low, high, data_arrays, ij_record):
data_arrays = self.slice_arrays(low, high, data_arrays)
nex = np.logical_or(data_arrays['injection_fraction'], np.logical_not(data_arrays['aav_exclusion_fraction']))
self.sum_pixels = data_arrays['sum_pixels'][nex].sum()
self.sum_pixels -= ij_record.sum_pixels
self.sum_projection_pixels = np.multiply(data_arrays['sum_pixels'], data_arrays['projection_density'])[nex].sum()
self.sum_projection_pixels -= ij_record.sum_projection_pixels
self.direct_sum_projection_pixels = self.sum_projection_pixels
self.sum_projection_pixel_intensity = np.multiply(data_arrays['sum_pixels'], data_arrays['projection_energy'])[nex].sum()
self.sum_projection_pixel_intensity -= ij_record.sum_projection_pixel_intensity
self.sum_pixel_intensity = float(data_arrays['sum_pixel_intensities'][nex].sum())
self.sum_pixel_intensity -= ij_record.sum_pixel_intensity
valid_density = np.multiply(nex, data_arrays['projection_density'])
valid_density = np.multiply(valid_density, 1 - data_arrays['injection_fraction'])
self.set_max_voxel(valid_density, low)