def determine_slice_flip(morphology: Morphology, soma_marker: Dict, slice_image_flip: bool): """ Determines whether the tilt correction should be positive or negative Parameters ---------- morphology: Morphology object soma_marker: soma marker dictionary from reconstruction marker file slice_image_flip: indicates whether the image was flipped relative to the slice (e.g the z axis of the image is opposite to the z axis in the slice) Returns ------- flip_toggle -1 or 1 to be multiplied against tilt correction """ flip_toggle = 1 morph_soma = morphology.get_soma() if (soma_marker['z'] - morph_soma['z']) > 0: flip_toggle = -1 if flip_toggle == 1 and not slice_image_flip: flip_toggle *= -1 return flip_toggle
def calculate_transform( gradient_field: xr.DataArray, morph: Morphology, node: Optional[List[float]] = None, ): theta = get_upright_angle(gradient_field, node) transform = np.eye(4) transform[0:3, 0:3] = aff.rotation_from_angle(theta) soma = morph.get_soma() cos_theta = np.cos(theta) sin_theta = np.sin(theta) transform[0:3, 3] = np.asarray([ -soma["x"] * cos_theta + soma["y"] * sin_theta + soma["x"], -soma["x"] * sin_theta - soma["y"] * cos_theta + soma["y"], 0 ]) output = { 'upright_transform': aff.AffineTransform(transform), 'upright_angle': theta } return output
def estimate_scale_correction(morphology: Morphology, soma_depth: float, soma_marker_z: float, cut_thickness: Optional[float] = 350): """ Estimate a scale factor to correct the reconstructed morphology for slice shrinkage Prior to reconstruction, the slice shrinks due to evaporation. This is most notable in the z axis, which is the slice thickness. To correct for shrinkage we compare soma depth within the slice obtained soon after cutting the slice to the fixed_soma_depth obtained during the reconstruction. Then the scale correction is estimated as: scale = soma_depth / fixed_soma_depth. This is sensible as long as the z span of the corrected reconstruction is contained within the slice thickness. Thus we also estimate the maximum scale correction as: scale_max = cut_thickness / z_span, and take the smaller of scale and scale_max Parameters ---------- morphology: Morphology object soma_depth: recorded depth of the soma when it was sliced soma_marker_z: soma marker z value from revised marker file (z is on the slice surface for the marker file) cut_thickness: thickness of the cut slice Returns ------- scale factor correction """ soma_morph_z = morphology.get_soma()['z'] fixed_depth = np.abs(soma_morph_z - soma_marker_z) scale = soma_depth / fixed_depth node_z = [node['z'] for node in morphology.nodes()] z_range = np.max(node_z) - np.min(node_z) scale_max = cut_thickness / z_range if scale > scale_max: scale = scale_max warnings.warn(f"Shrinkage scale correction factor: {scale} " f"exceeded the max allowed value: {scale_max}. " f"Will correct for shrinkage using the maximum value." ) return scale