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
def morphology_png_to_s3(bucket: str, key: str, morphology: Morphology): tmp_path = key.split("/")[-1] nodes = morphology.nodes() x = [node['x'] for node in nodes] y = [node['y'] for node in nodes] z = [node['z'] for node in nodes] fig, ax = plt.subplots(1, 2) ax[0].scatter(x, y, s=0.1) ax[0].set_title('x-y view') ax[1].scatter(z, y, s=0.1) ax[1].set_title('z-y view') fig.suptitle(tmp_path[:-4], fontsize=16) fig.savefig(tmp_path) s3.upload_file(Filename=tmp_path, Bucket=bucket, Key=key) os.remove(tmp_path) return key
def transform_morphology( self, morphology: Morphology, clone: bool = False, scale_radius: bool = True, ) -> Morphology: """ Apply this transform to all nodes in a morphology. Parameters ---------- morphology: a Morphology loaded from an swc file clone: make a new object if True scale_radius: apply radius scaling if True Returns ------- A Morphology """ if clone: morphology = morphology.clone() if scale_radius: scaling_factor = self._get_scaling_factor() else: scaling_factor = 1 for node in morphology.nodes(): coordinates = np.array((node['x'], node['y'], node['z']), dtype=float) new_coordinates = self.transform(coordinates) node['x'] = new_coordinates[0] node['y'] = new_coordinates[1] node['z'] = new_coordinates[2] # approximate with uniform scaling in each dimension node['radius'] *= scaling_factor return morphology