def stack_hitology_volumes(rabbit, block_paths): def_ablations = [] def_combineds = [] out_dir = f'/hdscratch/ucair/{rabbit}/microscopic/recons/' if not os.path.exists(out_dir): os.makedirs(out_dir) for block_path in block_paths: block = block_path.split('/')[-1] histology_dir = f'/hdscratch/ucair/{rabbit}/microscopic/{block}/' def_dir = f'{histology_dir}/volume/deformable/' # Load the deformed volume def_ablation = io.LoadITKFile(f'{def_dir}/{block}_ablation_segmentation_to_exvivo.mhd', device=device) # def_combined = io.LoadITKFile(f'{def_dir}/{block}_ablation_and_transition_segmentation_to_invivo.mhd', # device=device) # Threshold the volume def_ablation.data = (def_ablation.data >= 0.8).float() # def_combined.data = (def_combined.data >= 0.8).float() def_ablations.append(def_ablation) # def_combineds.append(def_combined) full_ablation = def_ablations[0].copy() full_ablation = full_ablation * 0.0 for i, v in enumerate(def_ablations, 1): if v.sum() != 0.0: io.SaveITKFile(v, f'/home/sci/blakez/test_outs/volume{i}.nii.gz') full_ablation = full_ablation + v full_ablation.data = (full_ablation.data > 0.0).float() io.SaveITKFile(full_ablation, f'{out_dir}all_ablation_segs_to_exvivo.mhd')
def stack_image_volumes(rabbit, block_paths, base_dir='/hdscratch/ucair/'): def_images = [] out_dir = f'{base_dir}{rabbit}/microscopic/recons/' if not os.path.exists(out_dir): os.makedirs(out_dir) for block_path in block_paths: block = block_path.split('/')[-1] histology_dir = f'{base_dir}{rabbit}/microscopic/{block}/' def_dir = f'{histology_dir}/volume/deformable/' # Load the deformed volume if not os.path.exists(f'{def_dir}/{block}_image_volume_to_invivo.mhd'): continue def_image = io.LoadITKFile( f'{def_dir}/{block}_image_volume_to_invivo.mhd', device=device) def_images.append(def_image.copy()) full_ablation = def_images[0].copy() full_ablation = full_ablation * 0.0 for v in def_images: full_ablation.data = torch.stack([full_ablation.data, v.data], dim=0).max(0)[0] io.SaveITKFile(full_ablation, f'{out_dir}all_images_to_invivo.mhd')
def blocks_to_exvivo(rabbit, base_dir='/hdscratch/ucair/'): # import RabbitCommon as rc base_path = f'{base_dir}{rabbit}/blockface/' block_list = sorted(glob.glob(f'{base_path}block*')) device = 'cuda:1' rerun = True # Deform all of the blocks for block_path in block_list: block = block_path.split('/')[-1] print(f'Deforming {block} ... ', end='') out_path = f'{base_path}{block}/' if not os.path.exists(f'{out_path}/volumes/deformable/'): os.makedirs(f'{out_path}/volumes/deformable/') bf_name = f'{block_path}/volumes/raw/scatter_volume.mhd' block_vol = io.LoadITKFile(bf_name, device=device) # generate the deformation to the stacked block if not os.path.exists(f'{out_path}/volumes/deformable/{block}_to_exvivo.nii.gz') or rerun: to_exvivo = generate(rabbit, block=block, source_space='blockface', target_space='exvivo', base_dir=base_dir) block_as_exvivo = so.ApplyGrid.Create(to_exvivo, device=device)(block_vol, to_exvivo) io.SaveITKFile(block_as_exvivo, f'{out_path}/volumes/deformable/{block}_to_exvivo.nii.gz') del block_as_exvivo, to_exvivo torch.cuda.empty_cache() print('done')
def deform_histology_volumes(rabbit, block): rerun = True blockface_dir = f'/hdscratch/ucair/{rabbit}/blockface/{block}/' histology_dir = f'/hdscratch/ucair/{rabbit}/microscopic/{block}/' raw_dir = f'{histology_dir}/volume/raw/' out_dir = f'{histology_dir}/volume/deformable/' if not os.path.exists(out_dir): os.makedirs(out_dir) if os.path.exists(f'{out_dir}/{block}_ablation_segmentation_to_exvivo.mhd') and not rerun: return deformation = generate(rabbit, block, source_space='blockface', target_space='exvivo') deformation.to_(device=device) # Load the original volume ablation_vol = io.LoadITKFile(f'{raw_dir}/{block}_ablation_segmentation.mhd', device=device) ablation_vol.data = (ablation_vol.data >= 0.5).float() # combined_vol = io.LoadITKFile(f'{raw_dir}/{block}_ablation_and_transition_segmentation.mhd', device=device) def_ablation = so.ApplyGrid.Create(deformation, device=device)(ablation_vol, deformation) # def_combined = so.ApplyGrid.Create(deformation, device=device)(combined_vol, deformation) io.SaveITKFile(def_ablation, f'{out_dir}/{block}_ablation_segmentation_to_exvivo.mhd')
def convert_hdf5(block_path, raw_mic_dir): block = block_path.split('/')[-1] mic_list = sorted(glob.glob(f'{block_path}/raw/*_image.tif')) # if mic_list == []: mic_list += sorted(glob.glob(f'{block_path}/raw/*_image.jpg')) img_nums = [x.split('/')[-1].split('_')[1] for x in mic_list] # Load the image for img in img_nums: print(f'Processing {block}, {img} ... ', end='') mic_file = f'{raw_mic_dir}{block}/hdf5/{block}_img{img}_image.hdf5' try: mic = io.LoadITKFile( f'{raw_mic_dir}{block}/raw/IMG_{img}_histopathology_image.tif') except RuntimeError: mic = io.LoadITKFile( f'{raw_mic_dir}{block}/raw/IMG_{img}_histopathology_image.jpg') with h5py.File(mic_file, 'w') as f: g = f.create_group('RawImage') g.create_dataset('ImageData', data=mic.data.numpy()) print('Done')
def deform_image_volumes(rabbit, block, base_dir='/hdscratch/ucair/'): histology_dir = f'{base_dir}{rabbit}/microscopic/{block}/' raw_dir = f'{histology_dir}/volume/raw/' out_dir = f'{histology_dir}/volume/deformable/' if not os.path.exists(out_dir): os.makedirs(out_dir) deformation = generate(rabbit, block, source_space='blockface', target_space='invivo', base_dir=base_dir, pad_mode='zeros') def_file = f'/home/sci/blakez/ucair/longitudinal/{rabbit}/' def_file += 'deformation_fields/Day3_non_contrast_VIBE_interday_deformation_incomp.nii.gz' day0 = io.LoadITKFile( f'/hdscratch/ucair/AcuteBiomarker/Data/{rabbit}/{rabbit}_day3_to_day0_phi_inv.nii.gz', device=device) deformation = so.ComposeGrids.Create( device=device, padding_mode='zeros')([day0, deformation]) deformation.to_(device=device) deformation.set_size((512, 512, 512)) # Load the original volume image_vol = io.LoadITKFile(f'{raw_dir}/{block}_image_volume.mhd', device=device) def_image = so.ApplyGrid.Create(deformation, device=device)(image_vol, deformation) test_diff_z = np.diff(deformation.data[0, :].cpu().numpy()) test_diff_y = np.diff(deformation.data[1, :].cpu().numpy()) test_diff_x = np.diff(deformation.data[2, :].cpu().numpy()) test_diff_z_small = np.abs(test_diff_z) >= 0.5 test_diff_y_small = np.abs(test_diff_y) >= 0.5 test_diff_x_small = np.abs(test_diff_x) >= 0.5 mask = np.logical_and(np.logical_and(test_diff_x == 0, test_diff_y == 0), test_diff_z == 0) mask_small = np.logical_and( np.logical_and(test_diff_x_small == 0, test_diff_y_small == 0), test_diff_z_small == 0) final_mask = np.logical_and(mask == False, mask_small == True) mask = torch.zeros_like(def_image.data)[0, None] mask[:, :, :, :-1] = torch.tensor(final_mask) def_image.data = def_image.data * mask io.SaveITKFile(def_image, f'{out_dir}/{block}_image_volume_to_invivo.mhd')
def stack_hitology_volumes(rabbit, block_paths, base_dir='/hdscratch/ucair/'): def_ablations = [] def_combineds = [] out_dir = f'{base_dir}{rabbit}/microscopic/recons/' if not os.path.exists(out_dir): os.makedirs(out_dir) for block_path in block_paths: block = block_path.split('/')[-1] histology_dir = f'{base_dir}{rabbit}/microscopic/{block}/' def_dir = f'{histology_dir}/volume/deformable/' # Load the deformed volume if not os.path.exists( f'{def_dir}/{block}_ablation_segmentation_to_invivo.mhd'): continue def_ablation = io.LoadITKFile( f'{def_dir}/{block}_ablation_segmentation_to_invivo.mhd', device=device) def_combined = io.LoadITKFile( f'{def_dir}/{block}_ablation_and_transition_segmentation_to_invivo.mhd', device=device) # Threshold the volume def_ablation.data = (def_ablation.data >= 0.8).float() def_combined.data = (def_combined.data >= 0.8).float() def_ablations.append(def_ablation) def_combineds.append(def_combined) full_ablation = def_ablations[0].copy() full_ablation = full_ablation * 0.0 for v in def_ablations: full_ablation = full_ablation + v full_ablation.data = (full_ablation.data > 0.0).float() io.SaveITKFile(full_ablation, f'{out_dir}all_ablation_segs_to_invivo.mhd') full_combined = def_ablations[0].copy() full_combined = full_combined * 0.0 for v in def_combineds: full_combined = full_combined + v full_combined.data = (full_combined.data > 0.0).float() io.SaveITKFile(full_combined, f'{out_dir}all_ablation_and_transition_segs_to_invivo.mhd')
def recon_prediction(pred, rabbit, region='test'): # Load the target volume data_dir = f'/hdscratch2/NoncontrastBiomarker/Data/' if region == 'train': mask = io.LoadITKFile(f'{data_dir}{rabbit}/{rabbit}_train_mask.nrrd') else: mask = io.LoadITKFile(f'{data_dir}{rabbit}/{rabbit}_thermal_tissue.nrrd') out_vol = mask.clone() if hasattr(pred, 'float'): out_vol.data[mask.data.bool()] = pred.float() else: out_vol.data[mask.data.bool()] = torch.tensor(pred).float() return out_vol
def main(rabbit, base_dir='/hdscratch/ucair/'): device = 'cuda:1' in_path = f'{base_dir}{rabbit}/mri/exvivo/volumes/raw/' out_base = f'{base_dir}{rabbit}/mri/exvivo/volumes/deformable/invivo/' if not os.path.exists(out_base): os.makedirs(out_base) to_invivo = generate(rabbit, source_space='exvivo', target_space='invivo', base_dir=base_dir) t2_file = sorted(glob.glob(f'{in_path}*t2*')) t1_file = sorted(glob.glob(f'{in_path}*VIBE*')) if len(t1_file) > 1: t1_file = [x for x in t1_file if '0p5' in x] exvivo_t2 = io.LoadITKFile(t2_file[0], device=device) exvivo_t1 = io.LoadITKFile(t1_file[0], device=device) def_t2 = so.ApplyGrid.Create(to_invivo, device=device)(exvivo_t2, to_invivo) def_t1 = so.ApplyGrid.Create(to_invivo, device=device)(exvivo_t1, to_invivo) io.SaveITKFile(def_t2, f'{out_base}exvivo_t2_def_to_invivo_{rabbit}.nii.gz') io.SaveITKFile(def_t1, f'{out_base}exvivo_t1_def_to_invivo_{rabbit}.nii.gz') # # # to_exvivo = generate(rabbit, source_space='invivo', target_space='exvivo') # to_exvivo_affine = generate_affine_only(rabbit, source_space='invivo', target_space='exvivo') # # invivo = io.LoadITKFile(sorted(glob.glob(f'/hdscratch/ucair/{rabbit}/mri/invivo/volumes/raw/*t2*'))[0], device=device) # aff_invivo = so.ApplyGrid.Create(to_exvivo_affine, device=device)(invivo, to_exvivo_affine) # def_invivo = so.ApplyGrid.Create(to_exvivo, device=device)(invivo, to_exvivo) # # io.SaveITKFile(aff_invivo, f'/home/sci/blakez/test_outs/invivo_aff_to_exvivo_npv_{rabbit}.nii.gz') # io.SaveITKFile(def_invivo, f'/home/sci/blakez/test_outs/invivo_def_to_exvivo_npv_{rabbit}.nii.gz') # # io.SaveITKFile(def_exvivo, f'{out_base}/invivo/{exvivo_name}_to_invivo.nii.gz') print('done')
def block_stitch(block_path): block = block_path.split('/')[-1] # Load the deformabale transformation phi = io.LoadITKFile(f'{block_path}/volumes/raw/{block}_phi_stitch.mhd', device=device) phi.set_size((60, 1024, 1024)) return phi
def get_day0_to_day3(data_path): # Load the deformabale transformation phi_inv = io.LoadITKFile( f'{data_path}/volumes/raw/day0_to_day3_phi_inv.mhd', device=device ) phi_inv.set_size((256, 256, 256)) return phi_inv
def stacked_blocks_to_block(block_path): block = block_path.split('/')[-1] # Need to determine the output grid output_grid = io.LoadITKFile( f'{block_path}/volumes/raw/difference_volume.mhd', device=device) aff_grid = core.StructuredGrid.FromGrid(output_grid, channels=3) del output_grid torch.cuda.empty_cache() aff_grid.set_size((60, 1024, 1024), inplace=True) aff_grid.set_to_identity_lut_() # Load the affine aff = np.loadtxt(f'{block_path}/surfaces/raw/{block}_rigid_tform.txt') aff = torch.tensor(aff, device=device, dtype=torch.float32) # Apply the FORWARD affine to the deformation # aff = aff.inverse() a = aff[0:3, 0:3].float() t = aff[-0:3, 3].float() # Create a deformation from the affine that lives in the stacked blocks space aff_grid.data = aff_grid.data.flip(0) aff_grid.data = torch.matmul( a, aff_grid.data.permute(list(range(1, 3 + 1)) + [0]).unsqueeze(-1)) aff_grid.data = (aff_grid.data.squeeze() + t).permute([-1] + list(range(0, 3))) aff_grid.data = aff_grid.data.flip(0) # Load the deformabale transformation phi = io.LoadITKFile(f'{block_path}/volumes/raw/{block}_phi_stacking.mhd', device=device) phi.set_size((60, 1024, 1024)) # Compose the grids deformation = so.ComposeGrids.Create(device=device)([aff_grid, phi]) return deformation
def mr_to_exvivo(day3_dir): output_grid = io.LoadITKFile( '/home/sci/blakez/ucair/18_047/rawVolumes/ExVivo_2018-07-26/011_----_3D_VIBE_0p5iso_cor_3ave.nii.gz', device=device) aff_grid = core.StructuredGrid.FromGrid(output_grid, channels=3) del output_grid torch.cuda.empty_cache() aff_grid.set_size((256, 256, 256), inplace=True) aff_grid.set_to_identity_lut_() # Load the affine aff = np.loadtxt(f'{day3_dir}surfaces/raw/exvivo_to_invivo_affine.txt') aff = torch.tensor(aff, device=device, dtype=torch.float32) # Apply the FORWARD affine to the deformation # aff = aff.inverse() a = aff[0:3, 0:3].float() t = aff[-0:3, 3].float() # Create a deformation from the affine that lives in the stacked blocks space aff_grid.data = aff_grid.data.flip(0) aff_grid.data = torch.matmul( a, aff_grid.data.permute(list(range(1, 3 + 1)) + [0]).unsqueeze(-1)) aff_grid.data = (aff_grid.data.squeeze() + t).permute([-1] + list(range(0, 3))) aff_grid.data = aff_grid.data.flip(0) # Load the defromabale transformation phi = io.LoadITKFile(f'{day3_dir}volumes/deformable/invivo_phi.mhd', device=device) phi.set_size((256, 256, 256)) deformation = so.ComposeGrids.Create(device=device)([aff_grid, phi]) return deformation
def block_stitch(rabbit, block, direction, base_dir='/hdscratch/ucair/'): # block = block_path.split('/')[-1] block_path = f'{base_dir}{rabbit}/blockface/{block}/' # Load the deformabale transformation stitch_block = io.LoadITKFile( f'{block_path}/volumes/raw/{block}_{direction}_stitch.mhd', device=device ) stitch_block.set_size((60, 1024, 1024)) return stitch_block
def generate_hist_label(rabbit, base_dir, out_path): rerun = True device = 'cuda:1' # if os.path.exists(f'{out_path}/{rabbit}_hist_label.nii.gz') and not rerun: # print(f'Processing label for {rabbit} ... done') # return print(f'Processing label for {rabbit} ... ', end='') # Get the path for the # try: deform = io.LoadITKFile(f'{out_path}/{rabbit}_day3_to_day0_phi_inv.nii.gz', device=device) # except: # def_file = f'/home/sci/blakez/ucair/longitudinal/{rabbit}/' # def_file += 'deformation_fields/Day3_non_contrast_VIBE_interday_deformation_incomp.nii.gz' # deform = io.LoadITKFile(def_file, device=device) # io.SaveITKFile(deform, f'{out_path}/{rabbit}_day3_to_day0_phi_inv.nii.gz') # Load the ablation to day3 segmentation hist_file = f'{base_dir}/{rabbit}/microscopic/recons/all_ablation_segs_to_invivo.nrrd' if not os.path.exists(hist_file): hist_file = f'{base_dir}/{rabbit}/microscopic/recons/all_ablation_segs_to_invivo.mhd' hist_seg = io.LoadITKFile(hist_file, device=device) def_hist = so.ApplyGrid.Create(deform, device=device)(hist_seg, deform) def_hist.to_('cpu') def_hist.data = (def_hist.data >= 0.5).float() def_hist_np = binary_erosion(binary_dilation(def_hist.data.squeeze(), iterations=4), iterations=4) def_hist.data = torch.tensor(def_hist_np).unsqueeze(0).float() io.SaveITKFile(def_hist, f'{out_path}/{rabbit}_hist_label.nii.gz') print('done')
def process_mrti_data(rabbit, out_path): rerun = False if os.path.exists(f'{out_path}/{rabbit}_thermal_vol.nii.gz') and not rerun: print(f'Processing MRTI for {rabbit} ... done') return print(f'Processing MRTI for {rabbit} ... ', end='') data_dir = f'/hdscratch/ucair/AcuteBiomarker/Data/mrti/' files = sorted(glob.glob(f'{data_dir}/*')) mat_file = [x for x in files if rabbit in x][0] mrti_dict = loadmat(mat_file) cs_data = np.transpose(mrti_dict['PosDCS'][:, :, :, 0:3], (2, 1, 0, 3)) mrti_data = np.transpose(mrti_dict['temps'], (2, 1, 0, 3)) ctd_map = np.nan_to_num(np.transpose(mrti_dict['CTD_Map'], (2, 1, 0)), nan=1.0) ctd_map = np.log(ctd_map) origin = np.ascontiguousarray(cs_data[0, 0, 0, ::-1]) thermal_vol = core.StructuredGrid(size=mrti_data.shape[0:3], origin=origin, spacing=torch.tensor([1.0, 1.0, 1.0]), tensor=torch.tensor(mrti_data).permute( 3, 0, 1, 2), channels=mrti_data.shape[-1]) log_ctd_map = core.StructuredGrid( size=mrti_data.shape[0:3], origin=origin, spacing=torch.tensor([1.0, 1.0, 1.0]), tensor=torch.tensor(ctd_map).unsqueeze(0), channels=1) io.SaveITKFile(thermal_vol, f'{out_path}/{rabbit}_thermal_vol.nii.gz') io.SaveITKFile(log_ctd_map, f'{out_path}/{rabbit}_log_ctd_map.nii.gz') print('done')
def generate_label_volume(rabbit, block): data_dir = f'/hdscratch/ucair/{rabbit}/blockface/{block}/' tif_files = sorted(glob.glob(f'{data_dir}volumes/raw/labels_tif/*')) hdr = read_mhd_header(f'{data_dir}volumes/raw/difference_volume.mhd') hdr['ElementDataFile'] = hdr['ElementDataFile'].replace( 'difference', 'segmentation') hdr['ElementNumberOfChannels'] = 1 # Load each of the tif images and then dump it into the label dir for tif_file in tif_files: tif_name = tif_file.split('/')[-1].split('.')[0] if os.path.exists( f'{data_dir}volumes/raw/segmentation/{tif_name}.mhd'): continue tif = io.LoadITKFile(tif_file) io.SaveITKFile(tif, f'{data_dir}volumes/raw/segmentation/{tif_name}.mhd') write_mhd_header(f'{data_dir}volumes/raw/segmentation_volume.mhd', hdr)
def get_mr_slice(mr_file, blockface, slice_num, sample_device='cpu'): orig_device = blockface.device mr_data = io.LoadITKFile(mr_file, device=sample_device) blockface.to_(sample_device) mr_resamp = so.ResampleWorld.Create(blockface, device=sample_device)(mr_data) mr_slice = mr_resamp.extract_slice(slice_num - 1, dim=0) mr_slice.to_(orig_device) blockface.to_(orig_device) del mr_data, mr_resamp torch.cuda.empty_cache() return mr_slice
def sort_and_label(in_dir, rabbit): out_base_dir = f'/hdscratch/ucair/{rabbit}/microscopic/' files = sorted(glob.glob(in_dir + '*')) label_files = [x for x in files if 'label' in x] image_files = [x for x in files if 'label' not in x] for im in range(0, len(image_files)): label = io.LoadITKFile(label_files[im]) plt.figure() plt.imshow(label.data.permute(1, 2, 0) / 255.0) plt.axis('off') plt.pause(1) block_num = input('Please input the block number [xx]: ') if block_num == 'skip': continue else: block_num = int(block_num) depth = int(input('Please input the depth of the section [xxx]: ')) image_num = int(depth / 50.0) + 1 out_image_dir = f'{out_base_dir}block{block_num:02d}/raw/' out_label_dir = f'{out_base_dir}block{block_num:02d}/raw_labels/' if not os.path.exists(out_image_dir): os.makedirs(out_image_dir) os.makedirs(out_label_dir) out_label = f'IMG_{image_num:03d}_histopathology_label.tif' out_image = f'IMG_{image_num:03d}_histopathology_image.tif' shutil.copy(label_files[im], f'{out_label_dir}{out_label}') if os.path.exists(f'{out_image_dir}{out_image}'): pass else: shutil.copy(image_files[im], f'{out_image_dir}{out_image}') plt.close('all')
def block_stacking(rabbit): rabbit_dir = f'/hdscratch2/{rabbit}/blockface/' raw_ext = '/surfaces/raw/' rigid_ext = '/surfaces/rigid/' deform_ext = '/surfaces/deformable/' vol_ext = '/volumes/raw/' stitch_ext = '/surfaces/raw/stitching/deformable/' # Get a list of the blocks block_list = sorted(glob.glob(f'{rabbit_dir}block*')) # for block_path in block_list: # block = block_path.split('/')[-1] # with open(f'{rabbit_dir}{block}{raw_ext}{block}_deformable_config.yaml', 'r') as f: # params = yaml.load(f, Loader=yaml.FullLoader) # params['propagation_sigma'] = [8.0, 8.0, 3.0] # params['currents_sigma'] = [3.0, 1.5] # with open(f'{rabbit_dir}{block}{raw_ext}{block}_deformable_config.yaml', 'w') as f: # yaml.dump(params, f) # Determine the middle block # middle_block = block_list[9] middle_block = block_list[5] foot_blocks = block_list[block_list.index(middle_block):] head_blocks = block_list[:block_list.index(middle_block) + 1][::-1] rerun = True rigid = False # skip_blocks = ['block01', 'block02', 'block03', 'block04', 'block05', 'block06', 'block07', 'block08'] skip_blocks = [] # Go ahead and just delete any deformable surfaces to make sure that everything resets # for block_path in block_list: # filelist = glob.glob(f'{block_path}/surfaces/deformable/*') # for f in filelist: # os.remove(f) if rerun or not os.path.exists( f'{middle_block}{vol_ext}{middle_block.split("/")[-1]}_phi_stacking.mhd' ): mid_block = middle_block.split('/')[-1] # middle = io.LoadITKFile(f'{middle_block}{vol_ext}difference_volume.mhd') middle = io.LoadITKFile( f'{middle_block}{vol_ext}difference_volume.nii.gz') # middle = io.LoadITKFile(f'{middle_block}{vol_ext}{mid_block}_volume.nrrd') middle.set_size((60, 1024, 1024)) deformation = core.StructuredGrid.FromGrid(middle, channels=3) deformation.set_to_identity_lut_() io.SaveITKFile( deformation, f'{middle_block}{vol_ext}{middle_block.split("/")[-1]}_phi_inv_stacking.mhd' ) io.SaveITKFile( deformation, f'{middle_block}{vol_ext}{middle_block.split("/")[-1]}_phi_stacking.mhd' ) affine_tform = torch.eye(4) np.savetxt( f'{rabbit_dir}{mid_block}{raw_ext}{mid_block}_rigid_tform.txt', affine_tform.numpy()) np.savetxt( f'{rabbit_dir}{mid_block}{vol_ext}{mid_block}_rigid_tform.txt', affine_tform.numpy()) # Copy the files from raw to deformable for the middle surface # if os.path.exists(f'{rabbit_dir}{mid_block}{stitch_ext}'): # mid_path = f'{mid_block}{stitch_ext}' # else: mid_path = f'{mid_block}{raw_ext}' files = [ f'{rabbit_dir}{mid_path}{mid_block}_decimate.obj', f'{rabbit_dir}{mid_path}{mid_block}_ext.obj', ] if os.path.exists(f'{rabbit_dir}{mid_path}{mid_block}_foot.obj'): files += [f'{rabbit_dir}{mid_path}{mid_block}_foot.obj'] if os.path.exists(f'{rabbit_dir}{mid_path}{mid_block}_head.obj'): files += [f'{rabbit_dir}{mid_path}{mid_block}_head.obj'] if os.path.exists( f'{rabbit_dir}{mid_path}{mid_block}_foot_support.obj'): files += [f'{rabbit_dir}{mid_path}{mid_block}_foot_support.obj'] if os.path.exists( f'{rabbit_dir}{mid_path}{mid_block}_head_support.obj'): files += [f'{rabbit_dir}{mid_path}{mid_block}_head_support.obj'] out_names = [] out_path = f'{rabbit_dir}{mid_block}{deform_ext}{mid_block}' for path in files: name = path.split('/')[-1].split(f'{mid_block}')[-1].replace( '.', '_deformable.') out_names += [f'{out_path}{name}'] if not os.path.exists(out_path): os.makedirs(out_path) for in_file, out_file in zip(files, out_names): shutil.copy(in_file, out_file) # Loop over the foot blocks for i, block_path in enumerate(foot_blocks, 1): if i == len(foot_blocks): break target_block = block_path.split('/')[-1] source_block = foot_blocks[i].split('/')[-1] if source_block in skip_blocks: continue # if os.path.exists(f'{rabbit_dir}{source_block}{stitch_ext}'): # mid_path = f'{source_block}{stitch_ext}' # else: mid_path = f'{source_block}{raw_ext}' target_surface_path = f'{rabbit_dir}{target_block}{deform_ext}{target_block}_foot_deformable.obj' source_surface_path = f'{rabbit_dir}{mid_path}{source_block}_head.obj' # if os.path.exists(f'{rabbit_dir}{mid_path}{source_block}_head_stitched.obj'): # source_surface_path = f'{rabbit_dir}{source_block}{raw_ext}{source_block}_head_stitched.obj' extras_paths = [ f'{rabbit_dir}{mid_path}{source_block}_decimate.obj', f'{rabbit_dir}{mid_path}{source_block}_ext.obj', ] if i < len(foot_blocks) - 1: extras_paths += [f'{rabbit_dir}{mid_path}{source_block}_foot.obj'] if os.path.exists( f'{rabbit_dir}{mid_path}{source_block}_foot_support.obj'): extras_paths += [ f'{rabbit_dir}{mid_path}{source_block}_foot_support.obj' ] if os.path.exists( f'{rabbit_dir}{source_block}{deform_ext}{source_block}_head_deformable.obj' ) and not rerun: print( f'The deformed surface for {source_block} already exists ... Next block' ) continue try: verts, faces = io.ReadOBJ(target_surface_path) tar_surface = core.TriangleMesh(verts, faces) tar_surface.to_(device) except IOError: print( f'The deformed foot surface for {target_block} was not found ... Next block' ) continue # Need to see if the target needs any support support_block = block_list[block_list.index(block_path) - 1].split('/')[-1] if os.path.exists( f'{rabbit_dir}{support_block}{deform_ext}{support_block}_foot_support_deformable.obj' ): verts, faces = io.ReadOBJ( f'{rabbit_dir}{support_block}{deform_ext}{support_block}_foot_support_deformable.obj' ) tar_surface.add_surface_(verts.to(device=device), faces.to(device=device)) try: verts, faces = io.ReadOBJ(source_surface_path) src_surface = core.TriangleMesh(verts, faces) src_surface.to_(device) src_surface.flip_normals_() except IOError: print( f'The raw head surface for {source_block} was not found ... Next block' ) continue extra_surfaces = [] for path in extras_paths: try: verts, faces = io.ReadOBJ(path) except IOError: extra_name = path.split('/')[-1] print( f'{extra_name} not found as an extra ... removing from list' ) _ = extras_paths.pop(extras_paths.index(path)) continue extra_surfaces += [core.TriangleMesh(verts, faces)] extra_surfaces[-1].to_(device) # Load or create the dictionary for registration try: if rerun: raise IOError with open( f'{rabbit_dir}{source_block}{raw_ext}{source_block}_affine_config.yaml', 'r') as f: params = yaml.load(f, Loader=yaml.FullLoader) except IOError: params = { 'spatial_sigma': [2.0, 0.5], 'affine_lr': 1.0e-08, 'translation_lr': 1.0e-05, 'converge': 1.0, 'rigid_transform': True } print(f'Registering {source_block} to {target_block}:') affine_tform = tools.affine_register( tar_surface.copy(), src_surface.copy(), spatial_sigma=params['spatial_sigma'], affine_lr=params['affine_lr'], translation_lr=params['translation_lr'], rigid=params['rigid_transform'], converge=params['converge'], device=device) # Apply the affine to the source element and the excess aff_tformer = uo.AffineTransformSurface.Create(affine_tform, device=device) aff_src_surface = aff_tformer(src_surface) aff_extra_surface = [] for surface in extra_surfaces: aff_extra_surface += [aff_tformer(surface)] out_path = f'{rabbit_dir}{source_block}{rigid_ext}{source_block}' if not os.path.exists(out_path): os.makedirs(out_path) for extra_path, extra_surface in zip(extras_paths, aff_extra_surface): name = extra_path.split('/')[-1].split( f'{source_block}')[-1].replace('.', '_rigid.') # if '_stitched' in name: # name = name.replace('_stitched', '') if not os.path.exists(f'{out_path}{name}') or rerun: io.WriteOBJ(extra_surface.vertices, extra_surface.indices, f'{out_path}{name}') if rigid: continue # Save out the parameters: with open( f'{rabbit_dir}{source_block}{raw_ext}{source_block}_affine_config.yaml', 'w') as f: yaml.dump(params, f) # Save out all of the affine transformed surfaces and the transformation out_path = f'{rabbit_dir}{source_block}{rigid_ext}{source_block}' # Save the affine in the volumes and in the surfaces location np.savetxt( f'{rabbit_dir}{source_block}{raw_ext}{source_block}_rigid_tform.txt', affine_tform.numpy()) np.savetxt( f'{rabbit_dir}{source_block}{vol_ext}{source_block}_rigid_tform.txt', affine_tform.numpy()) if not os.path.exists(f'{out_path}_head_rigid.obj') or rerun: io.WriteOBJ(aff_src_surface.vertices, aff_src_surface.indices, f'{out_path}_head_rigid.obj') for extra_path, extra_surface in zip(extras_paths, aff_extra_surface): name = extra_path.split('/')[-1].split( f'{source_block}')[-1].replace('.', '_rigid.') if not os.path.exists(f'{out_path}{name}') or rerun: io.WriteOBJ(extra_surface.vertices, extra_surface.indices, f'{out_path}{name}') try: if rerun: raise IOError with open( f'{rabbit_dir}{source_block}{raw_ext}{source_block}_deformable_config.yaml', 'r') as f: params = yaml.load(f, Loader=yaml.FullLoader) except IOError: params = { 'currents_sigma': [3.0, 0.5], 'propagation_sigma': [6.0, 6.0, 3.0], 'deformable_lr': [1.0e-04, 0.5e-04], 'converge': 1.0, 'grid_size': [20, 100, 100], 'niter': 500 } # params = { # 'currents_sigma': [3.0, 1.5], # 'propagation_sigma': [6.0, 6.0, 3.0], # 'deformable_lr': [2.0e-04, 1.0e-04], # 'converge': 1.0, # 'grid_size': [20, 100, 100], # 'niter': 500 # } # Account for some old parameter names - can be deleted later if 'spatial_sigma' in params.keys(): params['currents_sigma'] = params['spatial_sigma'] del params['spatial_sigma'] if 'phi_inv_size' in params.keys(): params['grid_size'] = params['phi_inv_size'] del params['phi_inv_size'] if 'rigid_transform' in params.keys(): del params['rigid_transform'] if 'smoothing_sigma' in params.keys(): params['propagation_sigma'] = params['smoothing_sigma'] del params['smoothing_sigma'] if type(params['deformable_lr']) is not list: params['deformable_lr'] = [params['deformable_lr']] * len( params['spatial_sigma']) # Do the deformable registration def_surface, def_extras, phi, phi_inv = tools.deformable_register( tar_surface.copy(), aff_src_surface.copy(), currents_sigma=params['currents_sigma'], prop_sigma=params['propagation_sigma'], deformable_lr=params['deformable_lr'], converge=params['converge'], grid_size=params['grid_size'], src_excess=aff_extra_surface, accu_forward=True, accu_inverse=True, device=device, grid_device='cuda:1', iters=params['niter']) # Save out the parameters: with open( f'{rabbit_dir}{source_block}{raw_ext}{source_block}_deformable_config.yaml', 'w') as f: yaml.dump(params, f) # Save out all of the deformable transformed surfaces and phi inv io.SaveITKFile( phi_inv, f'{rabbit_dir}{source_block}{vol_ext}{source_block}_phi_inv_stacking.mhd' ) io.SaveITKFile( phi, f'{rabbit_dir}{source_block}{vol_ext}{source_block}_phi_stacking.mhd' ) out_path = f'{rabbit_dir}{source_block}{deform_ext}{source_block}' if not os.path.exists(out_path): os.makedirs(out_path) if not os.path.exists(f'{out_path}_head_deformable.obj') or rerun: io.WriteOBJ(def_surface.vertices, def_surface.indices, f'{out_path}_head_deformable.obj') for extra_path, extra_surface in zip(extras_paths, def_extras): name = extra_path.split('/')[-1].split( f'{source_block}')[-1].replace('.', '_deformable.') # if '_stitched' in name: # name = name.replace('_stitched', '') if not os.path.exists(f'{out_path}{name}') or rerun: io.WriteOBJ(extra_surface.vertices, extra_surface.indices, f'{out_path}{name}') print('Done registering foots blocks to middle block.') # Loop over the head blocks for i, block_path in enumerate(head_blocks, 1): if i == len(head_blocks): break target_block = block_path.split('/')[-1] source_block = head_blocks[i].split('/')[-1] if source_block in skip_blocks: continue if os.path.exists(f'{rabbit_dir}{source_block}{stitch_ext}'): mid_path = f'{source_block}{stitch_ext}' else: mid_path = f'{source_block}{raw_ext}' target_surface_path = f'{rabbit_dir}{target_block}{deform_ext}{target_block}_head_deformable.obj' source_surface_path = f'{rabbit_dir}{mid_path}{source_block}_foot.obj' if os.path.exists( f'{rabbit_dir}{mid_path}{source_block}_foot_stitched.obj'): source_surface_path = f'{rabbit_dir}{mid_path}{source_block}_foot_stitched.obj' extras_paths = [ f'{rabbit_dir}{mid_path}{source_block}_decimate.obj', f'{rabbit_dir}{mid_path}{source_block}_ext.obj' ] if i < len(head_blocks) - 1: extras_paths += [f'{rabbit_dir}{mid_path}{source_block}_head.obj'] if os.path.exists( f'{rabbit_dir}{mid_path}{source_block}_head_support.obj'): extras_paths += [ f'{rabbit_dir}{mid_path}{source_block}_head_support.obj' ] if os.path.exists( f'{rabbit_dir}{source_block}{deform_ext}{source_block}_foot_deformable.obj' ) and not rerun: print( f'The deformed surface for {source_block} already exists ... Next block' ) continue try: verts, faces = io.ReadOBJ(target_surface_path) tar_surface = core.TriangleMesh(verts, faces) tar_surface.to_(device) except IOError: print( f'The deformed foot surface for {target_block} was not found ... Next block' ) continue # Need to see if the target needs any support support_block = block_list[block_list.index(block_path) + 1].split('/')[-1] if os.path.exists( f'{rabbit_dir}{support_block}{deform_ext}{support_block}_head_support_deformable.obj' ): verts, faces = io.ReadOBJ( f'{rabbit_dir}{support_block}{deform_ext}{support_block}_head_support_deformable.obj' ) tar_surface.add_surface_(verts.to(device=device), faces.to(device=device)) try: verts, faces = io.ReadOBJ(source_surface_path) src_surface = core.TriangleMesh(verts, faces) src_surface.to_(device) src_surface.flip_normals_() except IOError: print( f'The raw foot surface for {source_block} was not found ... Next block' ) continue extra_surfaces = [] for path in extras_paths: try: verts, faces = io.ReadOBJ(path) except IOError: extra_name = path.split('/')[-1] print( f'{extra_name} not found as an extra ... removing from list' ) _ = extras_paths.pop(extras_paths.index(path)) continue extra_surfaces += [core.TriangleMesh(verts, faces)] extra_surfaces[-1].to_(device) # Load or create the dictionary for registration try: if rerun: raise IOError with open( f'{rabbit_dir}{source_block}{raw_ext}{source_block}_affine_config.yaml', 'r') as f: params = yaml.load(f, Loader=yaml.FullLoader) except IOError: params = { 'spatial_sigma': [2.0, 0.5], 'affine_lr': 1.0e-08, 'translation_lr': 1.0e-05, 'converge': 1.0, 'rigid_transform': True } print(f'Registering {source_block} to {target_block}:') affine_tform = tools.affine_register( tar_surface.copy(), src_surface.copy(), spatial_sigma=params['spatial_sigma'], affine_lr=params['affine_lr'], translation_lr=params['translation_lr'], rigid=params['rigid_transform'], converge=params['converge'], device=device) # Apply the affine to the source element and the excess aff_tformer = uo.AffineTransformSurface.Create(affine_tform, device=device) aff_src_surface = aff_tformer(src_surface) aff_extra_surface = [] for surface in extra_surfaces: aff_extra_surface += [aff_tformer(surface)] out_path = f'{rabbit_dir}{source_block}{rigid_ext}{source_block}' if not os.path.exists(out_path): os.makedirs(out_path) for extra_path, extra_surface in zip(extras_paths, aff_extra_surface): name = extra_path.split('/')[-1].split( f'{source_block}')[-1].replace('.', '_rigid.') if '_stitched' in name: name = name.replace('_stitched', '') if not os.path.exists(f'{out_path}{name}') or rerun: io.WriteOBJ(extra_surface.vertices, extra_surface.indices, f'{out_path}{name}') if rigid: continue # Save out the parameters: with open( f'{rabbit_dir}{source_block}{raw_ext}{source_block}_affine_config.yaml', 'w') as f: yaml.dump(params, f) # Save out all of the affine transformed surfaces and the transformation out_path = f'{rabbit_dir}{source_block}{rigid_ext}{source_block}' # Save the affine in the volumes and in the surfaces location np.savetxt( f'{rabbit_dir}{source_block}{raw_ext}{source_block}_rigid_tform.txt', affine_tform.numpy()) np.savetxt( f'{rabbit_dir}{source_block}{vol_ext}{source_block}_rigid_tform.txt', affine_tform.numpy()) if not os.path.exists(f'{out_path}_foot_rigid.obj') or rerun: io.WriteOBJ(aff_src_surface.vertices, aff_src_surface.indices, f'{out_path}_foot_rigid.obj') for extra_path, extra_surface in zip(extras_paths, aff_extra_surface): name = extra_path.split('/')[-1].split( f'{source_block}')[-1].replace('.', '_rigid.') if not os.path.exists(f'{out_path}{name}') or rerun: io.WriteOBJ(extra_surface.vertices, extra_surface.indices, f'{out_path}{name}') try: if rerun: raise IOError with open( f'{rabbit_dir}{source_block}{raw_ext}{source_block}_deformable_config.yaml', 'r') as f: params = yaml.load(f, Loader=yaml.FullLoader) except IOError: params = { 'currents_sigma': [3.0, 0.5], 'propagation_sigma': [6.0, 6.0, 3.0], 'deformable_lr': [1.0e-04, 0.5e-04], 'converge': 1.0, 'grid_size': [20, 100, 100], 'niter': 500 } # if 'spatial_sigma' in params.keys(): # params['currents_sigma'] = params['spatial_sigma'] # del params['spatial_sigma'] # if 'phi_inv_size' in params.keys(): # params['grid_size'] = params['phi_inv_size'] # del params['phi_inv_size'] # if 'rigid_transform' in params.keys(): # del params['rigid_transform'] # if 'smoothing_sigma' in params.keys(): # params['propagation_sigma'] = params['smoothing_sigma'] # del params['smoothing_sigma'] # # if type(params['deformable_lr']) is not list: # params['deformable_lr'] = [params['deformable_lr']] * len(params['spatial_sigma']) # Do the deformable registration def_surface, def_extras, phi, phi_inv = tools.deformable_register( tar_surface.copy(), aff_src_surface.copy(), currents_sigma=params['currents_sigma'], prop_sigma=params['propagation_sigma'], deformable_lr=params['deformable_lr'], converge=params['converge'], grid_size=params['grid_size'], src_excess=aff_extra_surface, accu_forward=True, accu_inverse=True, device=device, grid_device='cuda:1', iters=params['niter']) # Save out the parameters: with open( f'{rabbit_dir}{source_block}{raw_ext}{source_block}_deformable_config.yaml', 'w') as f: yaml.dump(params, f) # Save out all of the deformable transformed surfaces and phi inv io.SaveITKFile( phi_inv, f'{rabbit_dir}{source_block}{vol_ext}{source_block}_phi_inv_stacking.mhd' ) io.SaveITKFile( phi, f'{rabbit_dir}{source_block}{vol_ext}{source_block}_phi_stacking.mhd' ) out_path = f'{rabbit_dir}{source_block}{deform_ext}{source_block}' if not os.path.exists(out_path): os.makedirs(out_path) if not os.path.exists(f'{out_path}_foot_deformable.obj') or rerun: io.WriteOBJ(def_surface.vertices, def_surface.indices, f'{out_path}_foot_deformable.obj') for extra_path, extra_surface in zip(extras_paths, def_extras): name = extra_path.split('/')[-1].split( f'{source_block}')[-1].replace('.', '_deformable.') # if '_stitched' in name: # name = name.replace('_stitched', '') if not os.path.exists(f'{out_path}{name}') or rerun: io.WriteOBJ(extra_surface.vertices, extra_surface.indices, f'{out_path}{name}') print('Done registering head blocks to middle block.')
def process_mic(rabbit): raw_mic_dir = f'/hdscratch/ucair/{rabbit}/microscopic/' bf_dir = f'/hdscratch/ucair/{rabbit}/blockface/' raw_bf_dir = f'/hdscratch/ucair/blockface/{rabbit}/' block_list = sorted(glob.glob(f'{raw_mic_dir}/*')) # for block_path in block_list: # block = block_path.split('/')[-1] # # mic_list = sorted(glob.glob(f'{block_path}/raw/*_image.tif')) # # img_nums = [x.split('/')[-1].split('_')[1] for x in mic_list] # # # Load the image # for img in img_nums: # print(f'Processing {block}, {img} ... ', end='') # mic_file = f'{raw_mic_dir}{block}/hdf5/{block}_img{img}_image.hdf5' # # mic = io.LoadITKFile(f'{raw_mic_dir}{block}/raw/IMG_{img}_histopathology_image.tif') # # with h5py.File(mic_file, 'w') as f: # g = f.create_group('RawImage') # g.create_dataset('ImageData', data=mic.data.numpy()) # # print('Done') for block_path in block_list: block = block_path.split('/')[-1] mic_list = sorted(glob.glob(f'{block_path}/raw/*_image.tif')) img_nums = [x.split('/')[-1].split('_')[1] for x in mic_list] for img in img_nums: mic_file = f'{raw_mic_dir}{block}/hdf5/{block}_img{img}_image.hdf5' mic_seg = f'{raw_mic_dir}{block}/hdf5/{block}_img{img}_label.hdf5' blockface_image = f'{bf_dir}{block}/volumes/raw/difference/IMG_{img}_difference.mhd' blockface_label = f'{bf_dir}{block}/volumes/raw/segmentation/IMG_{img}_segmentation.mhd' meta_dict = {} with h5py.File(mic_file, 'r') as f: for key in f['RawImage'].attrs: meta_dict[key] = f['RawImage'].attrs[key] if 'Affine' in meta_dict.keys(): continue blockface = io.LoadITKFile(blockface_image, device=device) label_data = io.LoadITKFile(blockface_label, device=device) blockface = (blockface - blockface.min()) / (blockface.max() - blockface.min()) label = blockface.clone() label.data = label_data.data.clone() print(f'Affine Registering ... ') aff_mic, aff_mic_seg, affine = tools.process_mic(mic_file, mic_seg, blockface, label, device=device) print(f'Done') aff_mic *= aff_mic_seg blockface *= label blockface_s = core.StructuredGrid.FromGrid( blockface, tensor=blockface[0].unsqueeze(0), channels=1) aff_mic = (aff_mic - aff_mic.min()) / (aff_mic.max() - aff_mic.min()) print(f'Deformable Registering Labels ... ') def_label, label_deformation = match_bf_mic(aff_mic_seg, label, steps=[0.01, 0.005], scales=[4, 1], gauss=True) print(f'Done') label_def_mic = so.ApplyGrid(label_deformation, device=device)(aff_mic, label_deformation) print(f'Deformable Registering Images ... ') def_image, image_deformation = match_bf_mic( label_def_mic, blockface_s, steps=[0.01, 0.01], scales=[2, 1], ) print(f'Done') composer = so.ComposeGrids(device=device, dtype=torch.float32, padding_mode='border') deformation = composer([image_deformation, label_deformation]) def_mic = so.ApplyGrid(deformation, device=device)(aff_mic, deformation) try: with h5py.File(mic_file, 'r') as f: mic = f['ImageData'][:] except KeyError: with h5py.File(mic_file, 'r') as f: mic = f['RawImage/ImageData'][:] mic = core.StructuredGrid(mic.shape[1:], tensor=torch.tensor(mic, dtype=torch.float32, device=device), device=device, dtype=torch.float32, channels=3) print('Saving ... ') with h5py.File(mic_file, 'w') as f: g = f.create_group('RawImage') d = f.create_group('Deformation') g.create_dataset('ImageData', data=mic.data.cpu().numpy()) d.create_dataset('Phi', data=deformation.data.cpu().numpy()) g.attrs['Shape'] = list(mic.shape()) g.attrs['Spacing'] = mic.spacing.tolist() g.attrs['Origin'] = mic.origin.tolist() g.attrs['Affine'] = affine.tolist() d.attrs['Shape'] = list(deformation.shape()) d.attrs['Spacing'] = deformation.spacing.tolist() d.attrs['Origin'] = deformation.origin.tolist() io.SaveITKFile( def_mic, f'{raw_mic_dir}{block}/volume/images/IMG_{img}_def_histopathology.mhd' ) print('Done') plt.close('all') print('All Done')
def stitch_surfaces(rabbit): rabbit_dir = f'/hdscratch/ucair/{rabbit}/blockface/' raw_ext = '/surfaces/raw/' vol_ext = '/volumes/raw/' # Get a list of the blocks block_list = sorted(glob.glob(f'{rabbit_dir}block*')) # complete = ['block08'] complete = ['block06', 'block09'] for i, block_path in enumerate(block_list): block = block_path.split('/')[-1] stitching_dir = f'{rabbit_dir}{block}{raw_ext}/stitching/' if block in complete: continue if not os.path.exists(stitching_dir): print(f'No stitching surfaces found for {block}.') continue target_surface_path = f'{stitching_dir}/raw/{block}_target_faces.obj' source_surface_path = f'{stitching_dir}/raw/{block}_source_faces.obj' # Load the target surface try: verts, faces = io.ReadOBJ(target_surface_path) tar_surface = core.TriangleMesh(verts, faces) tar_surface.to_(device) except IOError: print( f'The target stitching surface for {block} was not found ... skipping' ) continue try: verts, faces = io.ReadOBJ(source_surface_path) src_surface = core.TriangleMesh(verts, faces) src_surface.to_(device) src_surface.flip_normals_() except IOError: print( f'The source stitching surface for {block} was not found ... skipping' ) continue # Need to load the exterior to drag along try: verts, faces = io.ReadOBJ( f'{rabbit_dir}/{block}/{raw_ext}/{block}_decimate.obj') surface_ext = core.TriangleMesh(verts, faces) surface_ext.to_(device) except IOError: print( f'The source stitching surface for {block} was not found ... skipping' ) continue # Determine the surface half way between the source and the target try: with open( f'{stitching_dir}/raw/{block}_middle_surface_config.yaml', 'r') as f: params = yaml.load(f, Loader=yaml.FullLoader) except IOError: params = { 'currents_sigma': [5.0, 0.25, 0.05], 'propagation_sigma': [1.0, 1.0, 1.0], 'deformable_lr': [0.0008, 0.01, 0.01], 'converge': 0.05, 'mid_offset': 0.5 } # Do the deformable registration def_src_surface, def_ext = tools.deformable_register( tar_surface.copy(), src_surface.copy(), src_excess=None, deformable_lr=params['deformable_lr'], currents_sigma=params['currents_sigma'], prop_sigma=params['propagation_sigma'], grid_size=None, converge=params['converge'], accu_forward=False, accu_inverse=False, device=device, ) new_verts = src_surface.vertices.clone() + ( (def_src_surface.vertices - src_surface.vertices) * params['mid_offset']) mid_surface = src_surface.copy() mid_surface.vertices = new_verts.clone() mid_surface.calc_normals() mid_surface.calc_centers() io.WriteOBJ( def_src_surface.vertices, def_src_surface.indices, f'{stitching_dir}/deformable_pieces/{block}_source_faces.obj') io.WriteOBJ( mid_surface.vertices, mid_surface.indices, f'{stitching_dir}/deformable_pieces/{block}_source_middle.obj') with open(f'{stitching_dir}/raw/{block}_middle_surface_config.yaml', 'w') as f: yaml.dump(params, f) # Load the binary volume for the block mask = io.LoadITKFile( f'{rabbit_dir}/{block}/{vol_ext}/segmentation_volume.mhd', device='cuda:0') # Load the other surfaces to drag along extras_paths = [ f'{rabbit_dir}{block}{raw_ext}{block}_decimate.obj', f'{rabbit_dir}{block}{raw_ext}{block}_ext.obj' ] if os.path.exists(f'{rabbit_dir}{block}{raw_ext}{block}_head.obj'): extras_paths += [f'{rabbit_dir}{block}{raw_ext}{block}_head.obj'] if os.path.exists(f'{rabbit_dir}{block}{raw_ext}{block}_foot.obj'): extras_paths += [f'{rabbit_dir}{block}{raw_ext}{block}_foot.obj'] if os.path.exists( f'{rabbit_dir}{block}{raw_ext}{block}_head_support.obj'): extras_paths += [ f'{rabbit_dir}{block}{raw_ext}{block}_head_support.obj' ] if os.path.exists( f'{rabbit_dir}{block}{raw_ext}{block}_foot_support.obj'): extras_paths += [ f'{rabbit_dir}{block}{raw_ext}{block}_foot_support.obj' ] extra_surfaces = [] for path in extras_paths: try: verts, faces = io.ReadOBJ(path) except IOError: extra_name = path.split('/')[-1] print( f'{extra_name} not found as an extra ... removing from list' ) _ = extras_paths.pop(extras_paths.index(path)) continue extra_surfaces += [core.TriangleMesh(verts, faces)] extra_surfaces[-1].to_(device) # Define the diffusion parameters for the registration try: with open(f'{stitching_dir}/raw/{block}_diffusion_config.yaml', 'r') as f: diff_params = yaml.load(f, Loader=yaml.FullLoader) except IOError: diff_params = { 'z_diff_c': 5.0, 'y_diff_c': 200.0, 'x_diff_c': 30.0, 'background_c': 0.5, 'niter': 10000, 'gamma': 0.0005, 'propegation_sigma': [0.2, 0.2, 0.2], 'grad_amp': 300.0 } try: with open( f'{stitching_dir}/raw/{block}_stitch_surface_config.yaml', 'r') as f: params = yaml.load(f, Loader=yaml.FullLoader) except IOError: params = { 'currents_sigma': [2.0, 1.0], 'smoothing_sigma': [2.0, 2.0, 2.0], 'deformable_lr': [0.0001, 0.001], 'grid_size': [40, 256, 256], 'converge': 0.05, 'grid_device': 'cpu', 'niters': 25 } # Do the deformable registration with the source to the mid def_src_surface, def_tar_surface, def_extra_surfaces, phi, phi_inv = deformable_register( tar_surface.copy(), src_surface.copy(), mid_surface.copy(), src_excess=extra_surfaces, deformable_lr=params['deformable_lr'], currents_sigma=params['currents_sigma'], prop_sigma=params['smoothing_sigma'], grid_size=params['grid_size'], converge=params['converge'], accu_forward=True, accu_inverse=True, grid_device=params['grid_device'], device=device, mask=mask, diff_params=diff_params, iters=params['niters']) with open(f'{stitching_dir}/raw/{block}_stitch_surface_config.yaml', 'w') as f: yaml.dump(params, f) with open(f'{stitching_dir}/raw/{block}_diffusion_config.yaml', 'w') as f: yaml.dump(diff_params, f) io.WriteOBJ( def_src_surface.vertices, def_src_surface.indices, f'{stitching_dir}/deformable/{block}_whole_stitched_decimate.obj') io.SaveITKFile(phi, f'{stitching_dir}/deformable/{block}_stitch_phi.mhd') io.SaveITKFile( phi_inv, f'{stitching_dir}/deformable/{block}_stitch_phi_inv.mhd') out_path = f'{stitching_dir}/deformable/' for extra_path, extra_surface in zip(extras_paths, def_extra_surfaces): name = extra_path.split('/')[-1] io.WriteOBJ(extra_surface.vertices, extra_surface.indices, f'{out_path}{name}') vol = io.LoadITKFile( '/hdscratch/ucair/18_047/blockface/block08/volumes/raw/difference_volume.mhd', device='cuda:0') # phi_inv.set_size((60, 1024, 1024)) # phi.set_size((60, 1024, 1024)) # resampled_stitched = so.ApplyGrid.Create(phi_inv, device='cuda:0')(vol, phi_inv) # resampled_unstitched = so.ApplyGrid.Create(phi, device='cuda:0')(resampled_stitched, phi) # io.SaveITKFile(resampled_stitched, '/home/sci/blakez/stitched_block08.mhd') # io.SaveITKFile(resampled_unstitched, '/home/sci/blakez/unstitched_block08.mhd') print(f'Done stitching {block} ... ')
def register_histopathology_to_blockface(rabbit, block, img_num, bf_slice): blockface_dir = f'/hdscratch/ucair/{rabbit}/blockface/{block}/' histology_dir = f'/hdscratch/ucair/{rabbit}/microscopic/{block}/' out_dir = f'{histology_dir}deformations/' if not os.path.exists(out_dir): os.makedirs(out_dir) # if os.path.exists(f'{out_dir}/img_{img_num}_deformation_to_blockface.mhd'): # return # Load and make the histopathology segmentation segs = [] segs += [ io.LoadITKFile( f'{histology_dir}segmentations/IMG_{img_num}/img_{img_num}_healthy_tissue.nrrd', device=device) ] if os.path.exists( f'{histology_dir}segmentations/IMG_{img_num}/img_{img_num}_ablated_region.nrrd' ): segs += [ io.LoadITKFile( f'{histology_dir}segmentations/IMG_{img_num}/img_{img_num}_ablated_region.nrrd', device=device) ] if os.path.exists( f'{histology_dir}segmentations/IMG_{img_num}/img_{img_num}_uncertain_region.nrrd' ): segs += [ io.LoadITKFile( f'{histology_dir}segmentations/IMG_{img_num}/img_{img_num}_uncertain_region.nrrd', device=device) ] histology_seg = core.StructuredGrid.FromGrid(segs[0], channels=1) for seg in segs: histology_seg += seg try: blockface_seg = io.LoadITKFile( f'{blockface_dir}volumes/raw/hd_labels/{block}_hdlabel_volume.nrrd', device=device) except: blockface_seg = io.LoadITKFile( f'{blockface_dir}volumes/raw/segmentation_volume.nrrd', device=device) # # Load the surface slice and get the difference # blockface_surf = io.LoadITKFile(f'{blockface_dir}volumes/raw/surface/IMG_{bf_slice:03d}_surface.mhd', # device=device) # # blockface_surf_p1 = io.LoadITKFile(f'{blockface_dir}volumes/raw/surface/IMG_{bf_slice + 1:03d}_surface.mhd', # device=device) # # diff = (blockface_surf - blockface_surf_p1).data[2] # # diff = (diff - diff.min()) / (diff.max() - diff.min()) # Extract the slice blockface_seg = blockface_seg.extract_slice(bf_slice - 1, dim=0) aff_seg, affine = solve_affine(histology_seg, blockface_seg, img_num, out_dir=out_dir, device=device) np.savetxt(f'{out_dir}/img_{img_num}_affine_to_blockface.txt', affine.cpu().numpy()) #### Apply the affine to the image mic_file = f'{histology_dir}hdf5/{block}_img{img_num}_image.hdf5' meta_dict = {} with h5py.File(mic_file, 'r') as f: mic = f['RawImage/ImageData'][:, ::10, ::10] for key in f['RawImage'].attrs: meta_dict[key] = f['RawImage'].attrs[key] mic = core.StructuredGrid(mic.shape[1:], tensor=torch.tensor(mic, dtype=torch.float32, device=device), spacing=torch.tensor([10.0, 10.0], dtype=torch.float32, device=device), origin=histology_seg.origin, device=device, dtype=torch.float32, channels=3) mic = (mic - mic.min()) / (mic.max() - mic.min()) aff_mic = so.AffineTransform.Create(affine=affine)(mic, blockface_seg) # plt.figure() # plt.imshow(aff_mic.data.permute(1,2,0).cpu()) # plt.axis('off') # plt.gca().invert_yaxis() # plt.savefig(f'/home/sci/blakez/ucair/Animations/Scrolls/Mic/Images/{blockface_slice}_image.png', dpi=500, bbox_inches='tight', pad_inches=0) def_histology, deformation = deformable_histology_to_blockface( aff_seg, blockface_seg, steps=[0.01, 0.005], scales=[4, 1], gauss=True, mic=aff_mic) # Save out the deformation io.SaveITKFile(deformation, f'{out_dir}/img_{img_num}_deformation_to_blockface.mhd')
def draw_contours(rabbit): raw_mic_dir = f'/hdscratch/ucair/{rabbit}/microscopic/' block_list = sorted(glob.glob(f'{raw_mic_dir}/*')) for block_path in block_list: block = block_path.split('/')[-1] mic_list = glob.glob(f'{block_path}/raw/*_image.tif') mic_list += glob.glob(f'{block_path}/raw/*_image.jpg') mic_list = sorted(mic_list) img_nums = [x.split('/')[-1].split('_')[1] for x in mic_list] for img in img_nums: mic_file = f'{raw_mic_dir}{block}/segmentations/IMG_{img}/img_{img}_color.nii.gz' healthy_file = f'{raw_mic_dir}{block}/segmentations/IMG_{img}/img_{img}_healthy_tissue.nrrd' uncertain_file = f'{raw_mic_dir}{block}/segmentations/IMG_{img}/img_{img}_uncertain_region.nrrd' ablation_file = f'{raw_mic_dir}{block}/segmentations/IMG_{img}/img_{img}_ablated_region.nrrd' # meta_dict = {} # with h5py.File(mic_file, 'r') as f: # mic = f['RawImage/ImageData'][:, ::10, ::10] # for key in f['RawImage'].attrs: # meta_dict[key] = f['RawImage'].attrs[key] # mic = core.StructuredGrid( # mic.shape[1:], # tensor=torch.tensor(mic, dtype=torch.float32, device=device), # spacing=torch.tensor([10.0, 10.0], dtype=torch.float32, device=device), # device=device, # dtype=torch.float32, # channels=3 # ) save = True contour_width = 1.0 mic = io.LoadITKFile(mic_file, device=device) parts = [io.LoadITKFile(healthy_file, device=device)] if os.path.exists(uncertain_file): parts += [io.LoadITKFile(uncertain_file, device=device)] if os.path.exists(ablation_file): parts += [io.LoadITKFile(ablation_file, device=device)] # mic = (mic - mic.min()) / (mic.max() - mic.min()) # labels = seg.slic(mic.data.cpu().permute(1, 2, 0).double().numpy(), 4, multichannel=True) part_contours = [] for p in parts: part_contours += [measure.find_contours(p.data.squeeze().cpu().numpy(), 0.5)] plt.figure() plt.imshow(mic.data.permute(1, 2, 0).cpu()) for contour in part_contours[0]: plt.plot(contour[:, 1], contour[:, 0], color='orange', linestyle='dashed', linewidth=contour_width) try: for contour in part_contours[1]: plt.plot(contour[:, 1], contour[:, 0], 'b-.', linewidth=contour_width) except IndexError: pass try: for contour in part_contours[2]: plt.plot(contour[:, 1], contour[:, 0], 'r:', linewidth=1.5) except IndexError: pass plt.axis('off') plt.show() plt.pause(1.0) out_path = f'{raw_mic_dir}{block}/segmentations/IMG_{img}/' if save: plt.savefig(f'{out_path}img_{img}_region_outlines.png', dpi=600, bbox_inches='tight', pad_inches=0) plt.figure() plt.imshow(mic.data.permute(1, 2, 0).cpu()) plt.axis('off') if save: plt.savefig(f'{out_path}img_{img}_original.png', dpi=600, bbox_inches='tight', pad_inches=0) plt.close('all') print(f'Done with {block}: {img}')
def exvivo_to_stacked_blocks(rabbit, block, direction, affine_only=False, base_dir='/hdscratch/ucair/'): # This is registered from blocks to exvivo, so phi is needed to bring the exvivo MR image to the block images # Need to determine the grid to sample the MR onto # rabbit_dir = f'/hdscratch/ucair/{rabbit}/blockface/' block_dir = f'{base_dir}{rabbit}/blockface/{block}/' exvivo_dir = f'{base_dir}{rabbit}/mri/exvivo/' # block_list = sorted(glob.glob(f'{rabbit_dir}block*')) # orig_dir = f'/home/sci/blakez/ucair/{rabbit}/rawVolumes/ExVivo_2018-07-26/' # Load the affine # try: # aff = np.loadtxt(f'{exvivo_dir}/surfaces/raw/blocks_to_exvivo_affine.txt') # aff = torch.tensor(aff, device=device, dtype=torch.float32) # except IOError: aff = np.loadtxt(os.path.normpath(f'{block_dir}../recons/surfaces/raw/blocks_to_exvivo_affine.txt')) aff = torch.tensor(aff, device=device, dtype=torch.float32) # if affine_only: # if direction == 'phi': # return aff.inverse() # else: # return aff # Load the deformation # try: # deformation = io.LoadITKFile( # f'{exvivo_dir}/volumes/raw/blocks_{direction}_to_exvivo.mhd', device=device # ) # deformation.set_size((256, 256, 256)) # except RuntimeError: deformation = io.LoadITKFile( os.path.normpath(f'{block_dir}../recons/surfaces/raw/blocks_{direction}_to_exvivo.mhd'), device=device ) deformation.set_size((256, 256, 256)) if affine_only: deformation.set_to_identity_lut_() if direction == 'phi': spacing = [] origin = [] size = [] # if 'block07' in block_path: # hdr = tools.read_mhd_header(f'{block_path}/volumes/raw/difference_volume.mhd') # else: hdr = tools.read_mhd_header(f'{block_dir}/volumes/raw/{block}_phi_inv_stacking.mhd') spacing.append(np.array([float(x) for x in hdr['ElementSpacing'].split(' ')])) origin.append(np.array([float(x) for x in hdr['Offset'].split(' ')])) size.append(np.array([float(x) for x in hdr['DimSize'].split(' ')])) spacing = np.stack(spacing) origin = np.stack(origin) size = np.stack(size) extent = size * spacing + origin aff_grid_size = np.array((512, 512, 512)) aff_grid_origin = np.min(origin, axis=0) aff_grid_spacing = (np.max(extent, axis=0) - aff_grid_origin) / aff_grid_size aff_grid = core.StructuredGrid( size=aff_grid_size.tolist()[::-1], spacing=aff_grid_spacing.tolist()[::-1], origin=aff_grid_origin.tolist()[::-1], device=device, channels=3 ) aff_grid.set_size(size=(512, 512, 512), inplace=True) aff_grid.set_to_identity_lut_() # Apply the FORWARD affine to the deformation a = aff[0:3, 0:3].float() t = aff[-0:3, 3].float() # Create a deformation from the affine that lives in the stacked blocks space aff_grid.data = aff_grid.data.flip(0) aff_grid.data = torch.matmul(a, aff_grid.data.permute(list(range(1, 3 + 1)) + [0]).unsqueeze(-1)) aff_grid.data = (aff_grid.data.squeeze() + t).permute([-1] + list(range(0, 3))) aff_grid.data = aff_grid.data.flip(0) # Compose the grids exvivo_to_blocks = so.ComposeGrids.Create(device=device)([aff_grid, deformation]) else: deformation.data = deformation.data.flip(0) # Apply the inverse affine to the grid aff = aff.inverse() a = aff[0:3, 0:3].float() t = aff[-0:3, 3].float() deformation.data = torch.matmul(a.unsqueeze(0).unsqueeze(0), deformation.data.permute(list(range(1, 3 + 1)) + [0]).unsqueeze(-1)) deformation.data = (deformation.data.squeeze() + t).permute([-1] + list(range(0, 3))) # Flip phi_inv back to the way it was deformation.data = deformation.data.flip(0) exvivo_to_blocks = deformation.copy() return exvivo_to_blocks
def mr_to_exvivo(rabbit, block, direction, affine_only=False, base_dir='/hdscratch/ucair/'): invivo_dir = f'{base_dir}{rabbit}/mri/invivo/' exvivo_dir = f'{base_dir}{rabbit}/mri/exvivo/' # Load the affine aff = np.loadtxt(f'{exvivo_dir}surfaces/raw/exvivo_to_invivo_affine.txt') aff = torch.tensor(aff, device=device, dtype=torch.float32) # if affine_only: # if direction == 'phi': # return aff.inverse() # else: # return aff # Load the deformation deformation = io.LoadITKFile( f'{exvivo_dir}volumes/raw/exvivo_to_invivo_{direction}.mhd', device=device ) deformation.set_size((256, 256, 256)) if affine_only: deformation.set_to_identity_lut_() if direction == 'phi': output_grid = io.LoadITKFile(f'{exvivo_dir}volumes/raw/reference_volume.nii.gz', device=device) aff_grid = core.StructuredGrid.FromGrid(output_grid, channels=3) del output_grid torch.cuda.empty_cache() aff_grid.set_size((256, 256, 256), inplace=True) aff_grid.set_to_identity_lut_() # Apply the FORWARD affine to the deformation a = aff[0:3, 0:3].float() t = aff[-0:3, 3].float() # Create a deformation from the affine that lives in the stacked blocks space aff_grid.data = aff_grid.data.flip(0) aff_grid.data = torch.matmul(a, aff_grid.data.permute(list(range(1, 3 + 1)) + [0]).unsqueeze(-1)) aff_grid.data = (aff_grid.data.squeeze() + t).permute([-1] + list(range(0, 3))) aff_grid.data = aff_grid.data.flip(0) invivo_exvivo = so.ComposeGrids.Create(device=device)([aff_grid, deformation]) else: deformation.data = deformation.data.flip(0) # Apply the inverse affine to the grid aff = aff.inverse() a = aff[0:3, 0:3].float() t = aff[-0:3, 3].float() deformation.data = torch.matmul(a.unsqueeze(0).unsqueeze(0), deformation.data.permute(list(range(1, 3 + 1)) + [0]).unsqueeze(-1)) deformation.data = (deformation.data.squeeze() + t).permute([-1] + list(range(0, 3))) # Flip phi_inv back to the way it was deformation.data = deformation.data.flip(0) invivo_exvivo = deformation.copy() return invivo_exvivo
def stacked_blocks_to_block(rabbit, block, direction, affine_only=False, base_dir='/hdscratch/ucair/'): block_dir = f'{base_dir}{rabbit}/blockface/{block}/' # Load the affine aff = np.loadtxt(os.path.normpath(f'{block_dir}/surfaces/raw/{block}_rigid_tform.txt')) aff = torch.tensor(aff, device=device, dtype=torch.float32) # if affine_only: # if direction == 'phi': # return aff.inverse() # else: # return aff # Load the deformabale transformation deformation = io.LoadITKFile( f'{block_dir}/volumes/raw/{block}_{direction}_stacking.mhd', device=device ) deformation.set_size((60, 1024, 1024)) if affine_only: deformation.set_to_identity_lut_() if direction == 'phi': # Need to determine the output grid output_grid = io.LoadITKFile(f'{block_dir}/volumes/raw/difference_volume.mhd', device=device) aff_grid = core.StructuredGrid.FromGrid(output_grid, channels=3) del output_grid torch.cuda.empty_cache() aff_grid.set_size((60, 1024, 1024), inplace=True) aff_grid.set_to_identity_lut_() # Apply the FORWARD affine to the deformation a = aff[0:3, 0:3].float() t = aff[-0:3, 3].float() # Create a deformation from the affine that lives in the stacked blocks space aff_grid.data = aff_grid.data.flip(0) aff_grid.data = torch.matmul(a, aff_grid.data.permute(list(range(1, 3 + 1)) + [0]).unsqueeze(-1)) aff_grid.data = (aff_grid.data.squeeze() + t).permute([-1] + list(range(0, 3))) aff_grid.data = aff_grid.data.flip(0) # Compose the grids stackblocks_to_block = so.ComposeGrids.Create(device=device)([aff_grid, deformation]) else: deformation.data = deformation.data.flip(0) # Apply the inverse affine to the grid aff = aff.inverse() a = aff[0:3, 0:3].float() t = aff[-0:3, 3].float() deformation.data = torch.matmul(a.unsqueeze(0).unsqueeze(0), deformation.data.permute(list(range(1, 3 + 1)) + [0]).unsqueeze(-1)) deformation.data = (deformation.data.squeeze() + t).permute([-1] + list(range(0, 3))) # Flip phi_inv back to the way it was deformation.data = deformation.data.flip(0) stackblocks_to_block = deformation.copy() return stackblocks_to_block
def exvivo_to_blocks(stacked_blocks_dir): # This is registered from blocks to exvivo, so phi is needed to bring the exvivo MR image to the block images # Need to determine the grid to sample the MR onto rabbit_dir = f'/hdscratch/ucair/{rabbit}/blockface/' block_list = sorted(glob.glob(f'{rabbit_dir}block*')) orig_dir = f'/home/sci/blakez/ucair/{rabbit}/rawVolumes/ExVivo_2018-07-26/' spacing = [] origin = [] size = [] for block_path in block_list: if 'block07' in block_path: hdr = tools.read_mhd_header(f'{block_path}/volumes/raw/difference_volume.mhd') else: hdr = tools.read_mhd_header(f'{block_path}/volumes/deformable/difference_volume_deformable.mhd') spacing.append(np.array([float(x) for x in hdr['ElementSpacing'].split(' ')])) origin.append(np.array([float(x) for x in hdr['Offset'].split(' ')])) size.append(np.array([float(x) for x in hdr['DimSize'].split(' ')])) spacing = np.stack(spacing) origin = np.stack(origin) size = np.stack(size) extent = size * spacing + origin aff_grid_size = np.array((512, 512, 512)) aff_grid_origin = np.min(origin, axis=0) aff_grid_spacing = (np.max(extent, axis=0) - aff_grid_origin) / aff_grid_size aff_grid = core.StructuredGrid( size=aff_grid_size.tolist()[::-1], spacing=aff_grid_spacing.tolist()[::-1], origin=aff_grid_origin.tolist()[::-1], device=device, channels=3 ) aff_grid.set_size(size=(512, 512, 512), inplace=True) aff_grid.set_to_identity_lut_() # Load the affine aff = np.loadtxt(f'{orig_dir}blocks_to_exvivo_affine.txt') aff = torch.tensor(aff, device=device, dtype=torch.float32) # Apply the FORWARD affine to the deformation # aff = aff.inverse() a = aff[0:3, 0:3].float() t = aff[-0:3, 3].float() # Create a deformation from the affine that lives in the stacked blocks space aff_grid.data = aff_grid.data.flip(0) aff_grid.data = torch.matmul(a, aff_grid.data.permute(list(range(1, 3 + 1)) + [0]).unsqueeze(-1)) aff_grid.data = (aff_grid.data.squeeze() + t).permute([-1] + list(range(0, 3))) aff_grid.data = aff_grid.data.flip(0) # Load the defromabale transformation phi = io.LoadITKFile( f'{orig_dir}blocks_phi_to_exvivo.mhd', device=device ) phi.set_size((256, 256, 256)) # Compose the grids deformation = so.ComposeGrids.Create(device=device)([aff_grid, phi]) return deformation
def mr_to_block(block_path, rabbit): day0_dir = f'/hdscratch/ucair/{rabbit}/mri/day0/' day3_dir = f'/hdscratch/ucair/{rabbit}/mri/invivo/' stacked_blocks_dir = f'/hdscratch/ucair/{rabbit}/blockface/recons/' block = block_path.split('/')[-1] # exvivo_out = f'/hdscratch/ucair/18_047/mri/exvivo/volumes/deformable/{block}/' invivo_out = f'/hdscratch/ucair/18_062/mri/day0/volumes/deformable/{block}/' if not os.path.exists(invivo_out): os.makedirs(invivo_out) deformations = [] # # Get the transformation from day0 to day3 # day0_to_day3 = get_day0_to_day3(day0_dir) # deformations.append(day0_to_day3) in_path = f'/hdscratch/ucair/{rabbit}/' # Need to load and deform the day 0 NPV volume day0_files = sorted(glob.glob(f'/scratch/rabbit_data/{rabbit}/rawVolumes/Ablation*/*')) # day3_files = sorted(glob.glob(f'{in_path}/mri/invivo/volumes/raw/*')) # hist_file = f'{in_path}/microscopic/recons/all_ablation_segs_to_invivo.nrrd' # if not os.path.exists(hist_file): # hist_file = f'{in_path}/microscopic/recons/all_ablation_segs_to_invivo.mhd' interday_file = sorted(glob.glob(f'{in_path}/mri/day0/volumes/raw/*')) log_ctd = '/hdscratch/ucair/AcuteBiomarker/Data/18_062/18_062_log_ctd_map.nii.gz' t1_nc_file = '/home/sci/blakez/ucair/longitudinal/18_062/Day0_non_contrast_VIBE.nii.gz' day0_npv_file = [x for x in day0_files if 'npv' in x or 'NPV' in x and '.nrrd' in x][0] day0_t1_file = [x for x in day0_files if '0.5x' in x][-1] # day3_npv_file = [x for x in day3_files if 'npv' in x or 'NPV' in x and '.nrrd' in x][0] interday = [x for x in interday_file if 'phi' in x and '.mhd' in x][0] day0_npv = io.LoadITKFile(day0_npv_file, device) day0_t1 = io.LoadITKFile(day0_t1_file, device) deform = io.LoadITKFile(interday, device) log_ctd = io.LoadITKFile(log_ctd, device) day0_nc_t1 = io.LoadITKFile(t1_nc_file, device) def_day0 = so.ApplyGrid.Create(deform, device=device)(day0_npv, deform) def_day0_t1 = so.ApplyGrid.Create(deform, device=device)(day0_t1, deform) def_log_ctd = so.ApplyGrid.Create(deform, device=device)(log_ctd, deform) def_nc_t1 = so.ApplyGrid.Create(deform, device=device)(day0_nc_t1, deform) to_block = gd.generate(rabbit, block=block, source_space='invivo', target_space='blockface') # Get the transformation with the affine included from invivo to exvivo # invivo_to_exvivo = mr_to_exvivo(day3_dir) # deformations.append(invivo_to_exvivo) # Get the transformation with the affine included from exvivo to the stacked blocks # exvivo_to_stacked = exvivo_to_blocks(stacked_blocks_dir) # deformations.append(exvivo_to_stacked) # # # Load the transformation from the stacked blocks to the block of interest # stacked_to_block = stacked_blocks_to_block(block_path) # deformations.append(stacked_to_block) # # Load the transformation for stitching if there is one # if os.path.exists(f'{block_path}/volumes/raw/{block}_phi_stitch.mhd'): # block_stitching = block_stitch(block_path) # deformations.append(block_stitching) # Load the Day3 MR file to be deformed # t2_motion = io.LoadITKFile( # '/home/sci/blakez/ucair/18_047/rawVolumes/Ablation_2018-06-28/089_----_t2_spc_1mm_iso_cor_post20min.nii.gz', # device=device # ) # # ce_t1 = io.LoadITKFile( # '/home/sci/blakez/ucair/18_047/rawVolumes/Ablation_2018-06-28/102_----_3D_VIBE_1mmIso_NoGrappa_1avg_fatsat_cor_00.nii.gz', # device=device # ) # npv = io.LoadITKFile( # '/hdscratch/ucair/18_062/mri/invivo/volumes/raw/028_----_Day3_lr_NPV_Segmentation_062.nrrd', # device=device # ) # ctd = io.LoadITKFile( # '/home/sci/blakez/ucair/18_047/rawVolumes/Ablation_2018-06-28/CTD_map.nrrd', # device=device # ) # ctd.data[ctd.data < 240] = 0.0 # ctd.data[ctd.data > 0.0] = 1.0 torch.cuda.empty_cache() # t2_to_block = so.ApplyGrid.Create(invivo_to_block, device=device, pad_mode='zeros')(t2_motion, invivo_to_block) # io.SaveITKFile(t2_to_block, f'{invivo_out}day0_t2_to_{block}.mhd') # # t1_to_block = so.ApplyGrid.Create(invivo_to_block, device=device, pad_mode='zeros')(ce_t1, invivo_to_block) # io.SaveITKFile(t1_to_block, f'{invivo_out}day0_ce_t1_to_{block}.mhd') npv_to_block = so.ApplyGrid.Create(to_block, device=device, pad_mode='zeros')(def_day0, to_block) io.SaveITKFile(npv_to_block, f'{invivo_out}day0_npv_to_{block}.mhd') t1_to_block = so.ApplyGrid.Create(to_block, device=device, pad_mode='zeros')(def_day0_t1, to_block) io.SaveITKFile(t1_to_block, f'{invivo_out}day0_t1_to_{block}.mhd') log_ctd_block = so.ApplyGrid.Create(to_block, device=device, pad_mode='zeros')(def_log_ctd, to_block) io.SaveITKFile(log_ctd_block, f'{invivo_out}day0_log_ctd_to_{block}.mhd') def_nc_t1 = so.ApplyGrid.Create(to_block, device=device, pad_mode='zeros')(def_nc_t1, to_block) io.SaveITKFile(def_nc_t1, f'{invivo_out}day0_t1_nc_to_{block}.mhd') # ctd_to_block = so.ApplyGrid.Create(invivo_to_block, device=device, pad_mode='zeros')(ctd, invivo_to_block) # io.SaveITKFile(ctd_to_block, f'{invivo_out}day0_ctd_to_{block}.mhd') print(f'Done with {block}')
def TPS(regObj, opt): import matplotlib matplotlib.use('qt5agg') import matplotlib.pyplot as plt plt.ion() # Load the points or ask where they are if not os.path.exists(f'{regObj.tps.outputPath}/tps_deformation.nii.gz' ) or regObj.tps.rerun: regObj.tps.outputPath = regObj.rabbitDirectory + '/tpsVolumes/' + regObj.pipelinePhase if not os.path.exists(regObj.tps.outputPath): os.makedirs(regObj.tps.outputPath) try: src_points = rc.load_slicer_points(regObj.tps.sourcePointsDir) tar_points = rc.load_slicer_points(regObj.tps.targetPointsDir) except IOError: regObj.tps.sourcePointsDir = _getFilePath( 'Source Points File ({0} TPS)'.format(regObj.pipelinePhase), initialdir=regObj.rabbitDirectory) regObj.tps.targetPointsDir = _getFilePath( 'Target Points File ({0} TPS)'.format(regObj.pipelinePhase), initialdir=regObj.rabbitDirectory) src_points = rc.load_slicer_points(regObj.tps.sourcePointsDir) tar_points = rc.load_slicer_points(regObj.tps.targetPointsDir) try: source_image = io.LoadITKFile(regObj.tps.source_image, opt.device) target_image = io.LoadITKFile(regObj.tps.target_image, opt.device) except RuntimeError: regObj.tps.source_image = _getFilePath( 'Source Image File (TPS)', initialdir=regObj.rabbitDirectory) regObj.tps.target_image = _getFilePath( 'Target Image File (TPS)', initialdir=regObj.rabbitDirectory) source_image = io.LoadITKFile(regObj.tps.source_image, opt.device) target_image = io.LoadITKFile(regObj.tps.target_image, opt.device) rbf_filter = so.RadialBasis.Create(tar_points, src_points, sigma=1.0, device=opt.device) # Solve for the rigid transform for determining the grid to sample onto rigidMat = rc.SolveRigidAffine(np.array(src_points), np.array(tar_points)) # Solve for the radial basis funtion deformation if regObj.tps.incompressible: rbf_source, rbf_grid = rbf_filter.filter_incompressible( in_grid=source_image, out_grid=target_image, t_step=10000, conv=0.8, step=0.03) else: rbf_source, rbf_grid = rbf_filter(in_grid=source_image, out_grid=target_image) io.SaveITKFile(rbf_grid, f'{regObj.tps.outputPath}/tps_deformation.nii.gz') else: rbf_grid = io.LoadITKFile( f'{regObj.tps.outputPath}/tps_deformation.nii.gz', device=opt.device) # Check if there are rigid volumes, if not, get them from the source volumes = sorted(glob.glob(regObj.rigid.outputPath + '/*')) if volumes == []: volumes = regObj.sourceVolumes print('Applying TPS transformation to source volumes .... ', end='') sys.stdout.flush() for volume in volumes: # Tag the file with 't' to indicate it had thin plate splines applied fileName = volume.split('/')[-1] fileName = fileName[:6] + 't' + fileName[7:] outName = os.path.join(regObj.tps.outputPath, fileName) if not os.path.exists(outName) or regObj.tps.rerun: # Load the source image src_im = io.LoadITKFile(volume, device=opt.device) aff_im = rc.SolveAffineGrid(src_im, np.array(rigidMat)) # Determine the subvol onto which the image needs to be resampled try: h_resample = so.ResampleWorld.Create( aff_im, device=opt.device)(rbf_grid) except RuntimeError: h_resample = so.ResampleWorld.Create( target_image, device=opt.device)(rbf_grid) # Apply and save if any(x in outName for x in ['MOCO', 'ADC', 't1_map']): def_im = so.ApplyGrid.Create(h_resample, device=opt.device, interp_mode='nearest')(src_im, h_resample) else: def_im = so.ApplyGrid.Create(h_resample, device=opt.device)(src_im, h_resample) io.SaveITKFile(def_im, outName) print('Done')