#-- INPUT FILE OPERATIONS ---------------------------------------------------# # determine image filetype and open print('Analyzing `' + p_img + '`...\n') print('Genes: ' + ', '.join(genes)) img, img_name, mtree = mf.open_image(p_img) if img_name[0].isdigit(): is_old_image = True img_dapi = su.normalize_image(img[-1,:,:,:]) imgs_rna = [su.normalize_image(img[i,:,:,:]) for i in range(len(genes))] if should_plot: su.animate_zstacks(imgs_rna + [img_dapi], vmax=[0.2]*len(imgs_rna) + [1], gif_name=os.path.join(outdir, 'anim', img_name+'_channels.gif')) # get voxel dimensions dim_iter = mtree.find('Metadata').find('Scaling').find('Items').findall('Distance') dims = {} for dimension in dim_iter: dim_id = dimension.get('Id') dims.update({dim_id:float(dimension.find('Value').text)*1.E6}) # [um] voxel_vol = dims['X'] * dims['Y'] * dims['Z'] # [um^3] dims_xyz = np.array([dims['X'], dims['Y'], dims['Z']]) # get channel wavelengths track_tree = mtree.find('Metadata').find('Experiment').find('ExperimentBlocks').find('AcquisitionBlock').find('MultiTrackSetup').findall('TrackSetup') tracks = [] for track in track_tree: name = track.get('Name')
s3_param = [[1, 0.75*t_spots[i]], [2, 0.75*t_spots[i]]] print('Identifying spots...') bw = dot_3d_wrapper(img_rna_smooth, s3_param) # watershed minArea = 4 Mask = morphology.remove_small_objects(bw>0, min_size=minArea, connectivity=1, in_place=False) labeled_mask = measure.label(Mask) print('Performing watershed segmentation...') peaks = feature.peak_local_max(imgs_rna[i],labels=labeled_mask, min_distance=2, indices=False) Seed = morphology.binary_dilation(peaks, selem=morphology.ball(1)) Watershed_Map = -1*distance_transform_edt(bw) seg = morphology.watershed(Watershed_Map, measure.label(Seed), mask=Mask, watershed_line=True) seg = morphology.remove_small_objects(seg>0, min_size=minArea, connectivity=1, in_place=False) print('Exporting mask...') outname = img_name + '_mask^' + g + '.tiff' p_out = os.path.join(outdir, 'masks', outname) seg = seg > 0 out=seg.astype(np.uint8) out[out>0]=255 writer = OmeTiffWriter(p_out, overwrite_file=True) writer.save(out) # output animation print('Exporting animation...') anim_name = img_name + '_mask^' + g + '.gif' su.animate_zstacks([imgs_rna[i].transpose(1,2,0), seg.astype(int).transpose(1,2,0)], vmax=[0.2, 1], gif_name=os.path.join(outdir, 'anim', anim_name))
if not p_blobs: p_blobs = [] for g in genes: p_blobs.append( os.path.join(outdir, 'masks', img_name + '_mask^' + g + '.tiff')) if img_name[0].isdigit(): is_old_image = True img_dapi = su.normalize_image(img[-1, :, :, :]) imgs_rna = [su.normalize_image(img[i, :, :, :]) for i in range(len(genes))] imgs_rna_unnormed = [img[i, :, :, :] for i in range(len(genes))] if should_plot: su.animate_zstacks(imgs_rna + [img_dapi], vmax=[0.2] * len(imgs_rna) + [1], gif_name=os.path.join(outdir, 'anim', img_name + '_channels.gif')) # get voxel dimensions dim_iter = mtree.find('Metadata').find('Scaling').find('Items').findall( 'Distance') dims = {} for dimension in dim_iter: dim_id = dimension.get('Id') dims.update({dim_id: float(dimension.find('Value').text) * 1.E6}) # [um] voxel_vol = dims['X'] * dims['Y'] * dims['Z'] # [um^3] dims_xyz = np.array([dims['X'], dims['Y'], dims['Z']]) # get channel wavelengths track_tree = mtree.find('Metadata').find('Experiment').find( 'ExperimentBlocks').find('AcquisitionBlock').find(
# split channels img_dapi = su.normalize_image(img[-1,:,:,:]) print('DAPI: ' + str(tracks[-1])) if fish_channel: try: img_rna = su.normalize_image(img[tracks.index(int(fish_channel)),:,:,:]) print('FISH: ' + fish_channel) except ValueError: raise ValueError('FISH channel not recognized. Must match one of the above tracks.') else: img_rna = su.normalize_image(img[0,:,:,:]) print('FISH: ' + str(tracks[0])) if should_plot: su.animate_zstacks([img_dapi, np.clip(img_rna, a_min=0, a_max=np.amax(img_rna)/5.)], titles=['DAPI', 'FISH, gain=5'], gif_name=os.path.join(outdir, 'anim', img_name+'_channels.gif')) #-- FIBER SEGMENTATION ------------------------------------------------------# print('\nSegmenting fiber from background...') img_fiber_only = mf.threshold_fiber(img_rna, t_fiber=t_fiber, verbose=True) # calculate volume of fiber volume = np.sum(img_fiber_only) * voxel_vol print('\nfiber = ' + str(float(100.*np.sum(img_fiber_only))/img_fiber_only.size) + '% of FOV') print('volume = ' + str(volume) + ' um^3') if should_plot: su.animate_zstacks([np.clip(img_rna, a_min=0, a_max=np.amax(img_rna)/5.), img_fiber_only], titles=['FISH, gain=5', 'fiber prediction'], gif_name=os.path.join(outdir, 'anim', img_name+'_fiber.gif'))
# construct allowed region for RNA mobility mask_allowed = np.logical_and(mask_fiber.astype(bool), np.logical_not(mask_nuc_eroded).astype(bool)) labeled_mask_allowed, n_regions = morphology.label(mask_allowed, return_num=True) voxel_counts = [] for l in range(1, n_regions + 1): voxel_counts.append(np.count_nonzero(labeled_mask_allowed == l)) mask_allowed = (labeled_mask_allowed == np.argmax(voxel_counts) + 1) tifffile.imwrite(os.path.join(outdir, img_name + '_allowed_region.tiff'), data=mask_allowed.transpose(2, 0, 1).astype(np.uint8) * 255, compress=6, photometric='minisblack') su.animate_zstacks([mask_fiber, mask_nuc, mask_allowed], titles=['fiber', 'nuclei', 'allowed'], gif_name=os.path.join(outdir, img_name + '_masks^' + gene + '.gif')) # create spawning probability matrix labeled_mask_nuc, n_nuc = morphology.label(mask_nuc, return_num=True) labeled_mask_nuc[mask_nuc_eroded == 1] = 0 labeled_mask_nuc[mask_allowed == 0] = 0 voxels_by_label = { l: np.count_nonzero(labeled_mask_nuc == l) for l in range(1, n_nuc + 1) } spawn_probs = np.zeros_like(mask_nuc, dtype=np.float32) sp_x = [] sp_P = [] for l in range(1, n_nuc + 1):
print('Genes: ' + ', '.join(genes)) img, img_name, mtree = mf.open_image(p_img) if transpose: img = img.transpose(0, 2, 1, 3) if img_name[0].isdigit(): is_old_image = True img_dapi = su.normalize_image(img[-1, :, :, :]) imgs_rna = [su.normalize_image(img[i, :, :, :]) for i in range(len(genes))] if should_plot: su.animate_zstacks(imgs_rna + [img_dapi], vmax=[0.2] * len(imgs_rna) + [1], gif_name=os.path.join(outdir, 'anim', img_name + '_channels.gif')) # get voxel dimensions dim_iter = mtree.find('Metadata').find('Scaling').find('Items').findall( 'Distance') dims = {} for dimension in dim_iter: dim_id = dimension.get('Id') dims.update({dim_id: float(dimension.find('Value').text) * 1.E6}) # [um] voxel_vol = dims['X'] * dims['Y'] * dims['Z'] # [um^3] dims_xyz = np.array([dims['X'], dims['Y'], dims['Z']]) with open(os.path.join(outdir, img_name + '_dims.csv'), 'w') as outfile: writer = csv.writer(outfile) writer.writerows([['x', dims['X']], ['y', dims['Y']], ['z', dims['Z']]])