コード例 #1
0
def generate_day0(ex_path, frame_dir, base_dir='/hdscratch/ucair/'):

    if not os.path.exists(frame_dir):
        os.makedirs(f'{frame_dir}/Images')
        os.makedirs(f'{frame_dir}/Contours')

    # file = '011_----_3D_VIBE_1mmIso_NoGrappa_1avg_fatsat_cor_POST_00.nii.gz'
    # npv_seg_file = '/hdscratch/ucair/18_047/mri/invivo/volumes/raw/Day3_NPV_segmentation_18_047.nrrd'
    # hst_seg_file = '/hdscratch/ucair/18_047/microscopic/recons/all_ablation_segs_to_invivo.nrrd'

    file = '/home/sci/blakez/ucair/longitudinal/18_047/Day0_contrast_VIBE.nii.gz'
    # file = '028_----_3D_VIBE_1mmIso_NoGrappa_1avg_fatsat_cor_Post_01.nii.gz'
    npv_seg_file = '/home/sci/blakez/ucair/longitudinal/18_047/Day0_Tumor_Segmentation_047.nrrd'
    # hst_seg_file = '/hdscratch/ucair/18_062/microscopic/recons/all_ablation_segs_to_invivo.mhd'

    images = io.LoadITKFile(file, device=device)
    npv_seg = io.LoadITKFile(npv_seg_file, device=device)
    # hst_seg = io.LoadITKFile(hst_seg_file, device=device)

    npv_seg = so.ResampleWorld.Create(images, device=device)(npv_seg)
    # hst_seg = so.ResampleWorld.Create(images, device=device)(hst_seg)

    npv_seg.data = (npv_seg.data >= 0.5).float()
    # hst_seg.data = (hst_seg.data >= 0.5).float()

    # hst_seg = torch.tensor(binary_erosion(binary_dilation(hst_seg.data.cpu().squeeze(), iterations=4), iterations=4))
    # hst_seg = hst_seg.unsqueeze(0)

    aspect = GetAspect(images)

    # for s in range(140, 201):
    for s in range(30, 85):
        # Extract the slice
        im_slice = images[:, s].squeeze().cpu()
        seg_slice = npv_seg[:, s].squeeze().cpu()
        # ext_slice = hst_seg[:, s].squeeze().cpu()

        # im_slice = im_slice[:, 80:-80]
        # seg_slice = seg_slice[:, 80:-80]
        # ext_slice = ext_slice[:, 80:-80]

        # plt.figure()
        # plt.imshow(im_slice, cmap='gray', aspect=1.0 / aspect, interpolation='nearest')
        # plt.axis('off')
        # plt.show()
        # plt.gca().invert_yaxis()
        # plt.savefig(f'{frame_dir}/Images/{s:03d}_image.png', dpi=600, bbox_inches='tight', pad_inches=0)
        #
        # plt.close('all')

        generate_slice(s,
                       im_slice,
                       seg_slice,
                       frame_dir,
                       aspect,
                       color='gold',
                       extra=None)

        print(f'Done with slice {s}/{int(images.size[0])}')
コード例 #2
0
def generate_exvivo(ex_path, frame_dir):

    tumor_seg_file = '/hdscratch/ucair/18_047/mri/exvivo/volumes/raw/T1_tumor_segmentation_exvivo_18_047.nrrd'
    ablation_seg_file = '/hdscratch/ucair/18_047/mri/exvivo/volumes/raw/T1_ablation_segmentation_exvivo_18_047.nrrd'
    exterior_seg_file = '/hdscratch/ucair/18_047/mri/exvivo/volumes/raw/T1_exterior_segmentation_18_047.nrrd'

    images = io.LoadITKFile(f'{ex_path}/011_----_3D_VIBE_0p5iso_cor_3ave.nrrd',
                            device=device)
    tumor_seg = io.LoadITKFile(tumor_seg_file, device=device)
    ablation_seg = io.LoadITKFile(ablation_seg_file, device=device)
    exterior_seg = io.LoadITKFile(exterior_seg_file, device=device)

    tumor_seg = so.ResampleWorld.Create(images, device=device)(tumor_seg)
    ablation_seg = so.ResampleWorld.Create(images, device=device)(ablation_seg)
    exterior_seg = so.ResampleWorld.Create(images, device=device)(exterior_seg)

    tumor_seg.data = (tumor_seg.data >= 0.5).float()
    ablation_seg.data = (ablation_seg.data >= 0.5).float()
    exterior_seg.data = (exterior_seg.data >= 0.5).float()

    aspect = GetAspect(images)

    for s in range(100, 253):
        # Extract the slice
        im_slice = images[:, s].squeeze().cpu()
        seg_slice = tumor_seg[:, s].squeeze().cpu(
        ) + ablation_seg[:, s].squeeze().cpu()
        ext_slice = exterior_seg[:, s].squeeze().cpu()

        im_slice = im_slice[:, 80:-80]
        seg_slice = seg_slice[:, 80:-80]
        ext_slice = ext_slice[:, 80:-80]

        # plt.figure()
        # plt.imshow(im_slice, cmap='gray', aspect=1.0 / aspect, interpolation='nearest')
        # plt.axis('off')
        # plt.show()
        # plt.gca().invert_yaxis()
        # plt.savefig(f'{frame_dir}/Images/{s:03d}_image.png', dpi=600, bbox_inches='tight', pad_inches=0)
        # plt.gca().invert_yaxis()
        #
        # plt.close('all')

        generate_slice(s,
                       im_slice,
                       seg_slice,
                       frame_dir,
                       aspect,
                       color=(0.114, 0.686, 0.666),
                       extra=ext_slice)

        print(f'Done with slice {s}/{int(images.size[0])}')
コード例 #3
0
def generate_invivo(ex_path, frame_dir):

    file = '011_----_3D_VIBE_1mmIso_NoGrappa_1avg_fatsat_cor_POST_00.nii.gz'
    tumor_seg_file = '/hdscratch/ucair/18_047/mri/invivo/volumes/raw/Day3_tumor_segmentation_18_047.nrrd'
    ablation_seg_file = '/hdscratch/ucair/18_047/mri/invivo/volumes/raw/Day3_NPV_segmentation_18_047.nrrd'

    images = io.LoadITKFile(f'{ex_path}/{file}', device=device)
    tumor_seg = io.LoadITKFile(tumor_seg_file, device=device)
    ablation_seg = io.LoadITKFile(ablation_seg_file, device=device)

    tumor_seg = so.ResampleWorld.Create(images, device=device)(tumor_seg)
    ablation_seg = so.ResampleWorld.Create(images, device=device)(ablation_seg)

    tumor_seg.data = (tumor_seg.data >= 0.5).float()
    ablation_seg.data = (ablation_seg.data >= 0.5).float()

    aspect = GetAspect(images)

    for s in range(140, 201):
        # Extract the slice
        im_slice = images[:, s].squeeze().cpu()
        seg_slice = tumor_seg[:, s].squeeze().cpu(
        ) + ablation_seg[:, s].squeeze().cpu()

        im_slice = im_slice[:, 80:-80]
        seg_slice = seg_slice[:, 80:-80]

        plt.figure()
        plt.imshow(im_slice,
                   cmap='gray',
                   aspect=1.0 / aspect,
                   interpolation='nearest')
        plt.axis('off')
        plt.show()
        plt.gca().invert_yaxis()
        plt.savefig(f'{frame_dir}/Images/{s:03d}_image.png',
                    dpi=600,
                    bbox_inches='tight',
                    pad_inches=0)

        plt.close('all')

        generate_slice(s,
                       im_slice,
                       seg_slice,
                       frame_dir,
                       aspect,
                       color=(0.8, 0.314, 0.016))

        print(f'Done with slice {s}/{int(images.size[0])}')
コード例 #4
0
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
コード例 #5
0
ファイル: get_mr_volumes.py プロジェクト: fuslab-uofu/MR_Hist
def main(rabbit):
    import RabbitCommon as rc

    in_path = f'/scratch/rabbit_data/{rabbit}/rawDicoms/ExVivo*/*'
    out_path = f'/hdscratch/ucair/{rabbit}/mri/exvivo/volumes/raw/'
    files = sorted(glob.glob(in_path))

    if not os.path.exists(out_path):
        os.makedirs(out_path)

    for cnt, dcm_file in enumerate(files):
        print(f'Processing {dcm_file} ... ', end='')

        out_name = dcm_file.split('/')[-1].split(' ')[-1]
        if os.path.exists(f'{out_path}{cnt:02d}_{out_name}.nii.gz'):
            print('done')
            continue
        vol = rc.LoadDICOM(dcm_file, 'cpu')
        io.SaveITKFile(vol, f'{out_path}{cnt:02d}_{out_name}.nii.gz')
        print('done')

    # Copy over some of the 'invivo' (day3)
    out_path = f'/hdscratch/ucair/{rabbit}/mri/invivo/volumes/raw/'
    in_path = f'/scratch/rabbit_data/{rabbit}/rawVolumes/Post*/*'
    files = sorted(glob.glob(in_path))
    filt_files = [x for x in files if '3D_VIBE_0.5' in x]
    filt_files += [x for x in files if 't2' in x]
    filt_files += [x for x in files if 'Day3' in x]

    if not os.path.exists(out_path):
        os.makedirs(out_path)

    for f in filt_files:
        shutil.copy(f, f'{out_path}{f.split("/")[-1]}')

    # Copy over some of the day0
    out_path = f'/hdscratch/ucair/{rabbit}/mri/day0/volumes/raw/'
    in_path = f'/scratch/rabbit_data/{rabbit}/rawVolumes/Ablation*/*'
    files = sorted(glob.glob(in_path))
    filt_files = [x for x in files if '3D_VIBE_0.5' in x]
    filt_files += [x for x in files if 't2' in x]
    filt_files += [x for x in files if 'Day0' in x]

    if not os.path.exists(out_path):
        os.makedirs(out_path)

    for f in filt_files:
        shutil.copy(f, f'{out_path}{f.split("/")[-1]}')
コード例 #6
0
def save_volume(vol, opt):
    import CAMP.Core as core
    import CAMP.FileIO as io
    # Bring the volume to the CPU
    vol = vol.to('cpu')
    out_path = f'{opt.hd_root}/{opt.rabbit}/blockface/{opt.block}/volumes/raw/'

    mhd_file = f'{out_path}/surface_volume.mhd'
    mhd_dict = read_mhd_header(mhd_file)

    data_files = f'predictions/IMG_%03d_prediction.raw 0 {vol.shape[0]} 1'
    mhd_dict['ElementDataFile'] = data_files
    mhd_dict['ElementNumberOfChannels'] = 1

    out_path = f'{out_path}/predictions/'
    try:
        os.stat(out_path)
    except OSError:
        os.makedirs(out_path)

    origin = [float(x) for x in mhd_dict['Offset'].split(' ')][0:2]
    spacing = [float(x) for x in mhd_dict['ElementSpacing'].split(' ')][0:2]

    # Loop over the firs dimension
    for s in range(0, vol.shape[0]):

        v_slice = core.StructuredGrid(
            vol.shape[1:],
            tensor=vol[s, :, :].unsqueeze(0),
            spacing=spacing,
            origin=origin,
            device='cpu',
            dtype=torch.float32,
            channels=1
        )

        # Generate the name for the image
        out_name = f'{out_path}IMG_{s:03d}_prediction.mhd'
        io.SaveITKFile(v_slice, out_name)

    write_mhd_header(f'{out_path}../prediction_volume.mhd', mhd_dict)
コード例 #7
0
def generate_blockface(in_dir, frame_dir):
    list = sorted(glob.glob(f'{in_dir}/*.mhd'))

    for i, file in enumerate(list):
        if i == 2 or i == 39:

            image = io.LoadITKFile(f'{file}').data.squeeze().permute(1, 2, 0)

            plt.figure()
            plt.imshow(image, cmap='gray', aspect=1.0, interpolation='nearest')
            plt.axis('off')
            plt.show()
            plt.gca().invert_yaxis()
            plt.savefig(f'{frame_dir}/Images/{i:03d}_image.png',
                        dpi=500,
                        bbox_inches='tight',
                        pad_inches=0)

            plt.close('all')

            print(f'Done with slice {i+1}/{len(list)}')
コード例 #8
0
def exvivo_to_stacked_blocks(rabbit,
                             block,
                             direction,
                             affine_only=False,
                             base_dir='/hdscratch/ucair/'):

    block_dir = f'{base_dir}{rabbit}/blockface/{block}/'
    exvivo_dir = f'{base_dir}{rabbit}/mri/exvivo/'

    # 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)

    # 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 = []

        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
コード例 #9
0
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)

    # 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
コード例 #10
0
def mr_to_exvivo(rabbit,
                 block,
                 direction,
                 affine_only=False,
                 base_dir='/hdscratch/ucair/'):

    # Generate the deformation from invivo to exvivo
    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)

    # 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
コード例 #11
0
               'cube': [64, 128, 128],
               'ckpt': '/usr/sci/scratch/blakez/blockface_data/output/2020-10-09-141713/epoch_200_model.pth',
               }

    evalOpt = SimpleNamespace(**evalOpt)
    trainOpt = SimpleNamespace(**trainOpt)

    # train(trainOpt)
    block_list = sorted(glob.glob(f'{evalOpt.hd_root}{evalOpt.rabbit}/blockface/block*'))
    for block_path in block_list[1:]:
        block = block_path.split('/')[-1]
        print(f'{block} ... ')

        import CAMP.Core as core
        import CAMP.FileIO as io
        scat_vol = io.LoadITKFile(f'{block_path}/volumes/raw/scatter_volume.mhd', device='cuda')
        grad_scat = scat_vol.data[:, :-1, :, :].cpu() - scat_vol.data[:, 1:, :, :].cpu()
        grad_scat = (grad_scat - grad_scat.min()) / (grad_scat.max() - grad_scat.min())
        grad_scat = torch.cat([grad_scat[:, 0, :, :].unsqueeze(1), grad_scat], dim=1)
        grad_scat = core.StructuredGrid(
            size=scat_vol.size,
            spacing=scat_vol.spacing,
            origin=scat_vol.origin,
            tensor=grad_scat[2].unsqueeze(0),
            device='cuda',
            channels=1
        )
        io.SaveITKFile(grad_scat, f'{block_path}/volumes/raw/scatter_gradient_volume.mhd')
        evalOpt.block = block
        eval(evalOpt)
        print(f'{block} ... done')
コード例 #12
0
def generate_invivo_hist(ex_path, frame_dir):

    if not os.path.exists(frame_dir):
        os.makedirs(f'{frame_dir}/Images')
        os.makedirs(f'{frame_dir}/Contours')

    # file = '011_----_3D_VIBE_1mmIso_NoGrappa_1avg_fatsat_cor_POST_00.nii.gz'
    # npv_seg_file = '/hdscratch/ucair/18_047/mri/invivo/volumes/raw/Day3_NPV_segmentation_18_047.nrrd'
    # hst_seg_file = '/hdscratch/ucair/18_047/microscopic/recons/all_ablation_segs_to_invivo.nrrd'

    # file = '028_----_3D_VIBE_1mmIso_NoGrappa_1avg_fatsat_cor_Post_01.nii.gz'
    file = '/home/sci/blakez/ucair/longitudinal/18_062/Day0_contrast_VIBE.nii.gz'
    t1_nc_file = '/home/sci/blakez/ucair/longitudinal/18_062/Day0_non_contrast_VIBE.nii.gz'
    # npv_seg_file = '/hdscratch/ucair/18_062/mri/invivo/volumes/raw/028_----_Day3_lr_NPV_Segmentation_062.nrrd'
    npv_seg_file = '/home/sci/blakez/ucair/longitudinal/18_062/Day0_NPV_Segmentation_062.nrrd'
    hst_seg_file = '/hdscratch/ucair/18_062/microscopic/recons/all_ablation_segs_to_invivo.mhd'
    log_ctd = '/hdscratch/ucair/AcuteBiomarker/Data/18_062/18_062_log_ctd_map.nii.gz'
    ctd_mask = '/hdscratch/ucair/AcuteBiomarker/Data/18_062/18_062_tissue_seg.nii.gz'

    images = io.LoadITKFile(file, device=device)
    t1_nc = io.LoadITKFile(t1_nc_file, device=device)
    npv_seg = io.LoadITKFile(npv_seg_file, device=device)
    hst_seg = io.LoadITKFile(hst_seg_file, device=device)
    log_ctd = io.LoadITKFile(log_ctd, device=device)
    ctd_mask = io.LoadITKFile(ctd_mask, device=device)
    log_ctd = log_ctd * ctd_mask

    npv_seg = so.ResampleWorld.Create(images, device=device)(npv_seg)
    t1_nc = so.ResampleWorld.Create(images, device=device)(t1_nc)
    hst_seg = so.ResampleWorld.Create(images, device=device)(hst_seg)
    log_ctd = so.ResampleWorld.Create(images, device=device)(log_ctd)

    npv_seg.data = (npv_seg.data >= 0.5).float()
    hst_seg.data = (hst_seg.data >= 0.5).float()

    # hst_seg = torch.tensor(binary_erosion(binary_dilation(hst_seg.data.cpu().squeeze(), iterations=4), iterations=4))
    # hst_seg = hst_seg.unsqueeze(0)

    aspect = GetAspect(images)

    ### ADDED
    #
    # def create_circular_mask(h, w, center=None, radius=None):
    #
    #     if center is None:  # use the middle of the image
    #         center = (int(w / 2), int(h / 2))
    #     if radius is None:  # use the smallest distance between the center and image walls
    #         radius = min(center[0], center[1], w - center[0], h - center[1])
    #
    #     Y, X = np.ogrid[:h, :w]
    #     dist_from_center = np.sqrt((X - center[0]) ** 2 + (Y - center[1]) ** 2)
    #
    #     mask = dist_from_center <= radius
    #     return mask
    #
    # slice_n = 130
    # green = matplotlib._cm._tab10_data[2]
    # blue = matplotlib._cm._tab10_data[0]
    # out_dir = '/home/sci/blakez/papers/dissertation/Day0and3NPV/'

    try:
        deform = io.LoadITKFile(
            f'/hdscratch/ucair/AcuteBiomarker/Data/{rabbit}/{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)

    def_hist = so.ApplyGrid.Create(deform, device=device)(hst_seg, deform)
    def_hist.to_('cpu')
    hst_seg.data = (hst_seg.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()
    hst_seg = def_hist
    # plt.figure()
    # plt.imshow(t1_nc.data.cpu()[0, slice_n].squeeze(), aspect=1.0 / aspect, cmap='gray')
    # plt.gca().invert_yaxis()
    # plt.axis('off')
    # plt.savefig(f'{out_dir}/day0_nc_t1.png', dpi=600, bbox_inches='tight', pad_inches=0, transparent=True)
    #
    # plt.figure()
    # plt.imshow(images.data.cpu()[0, slice_n].squeeze(), aspect=1.0 / aspect, cmap='gray')
    # plt.gca().invert_yaxis()
    # plt.axis('off')
    # plt.savefig(f'{out_dir}/day0_c_t1.png', dpi=600, bbox_inches='tight', pad_inches=0, transparent=True)

    # slice_im = t1_nc.data.cpu()[0, slice_n].squeeze()
    # zero_slice = np.zeros_like(slice_im)
    # masked_slice = np.ma.masked_where(zero_slice == 0.0, zero_slice).squeeze()
    # plt.figure()
    # plt.imshow(masked_slice.squeeze(), aspect=1.0 / aspect, cmap='gray')
    # npv_slice = hst_seg.data.cpu()[0, slice_n].squeeze()
    # npv_contours = measure.find_contours(npv_slice.data.squeeze().cpu().numpy(), 0.5)
    # for contour in npv_contours:
    #     plt.plot(contour[:, 1], contour[:, 0], color=matplotlib._cm._tab10_data[6], linewidth=1.8)
    # plt.gca().invert_yaxis()
    # plt.gca().patch.set_facecolor([0, 0, 0, 0])
    # plt.axis('off')
    # plt.savefig(f'{out_dir}/day0_contour_hist.png', dpi=600, bbox_inches='tight', pad_inches=0, transparent=True)
    #
    # from matplotlib.colors import LinearSegmentedColormap
    # colors = [(0.0, 0.0, 0.0), (0.8901960784313725, 0.4666666666666667, 0.7607843137254902)]
    # cm = LinearSegmentedColormap.from_list('hist_color', colors, N=1)
    # plt.figure()
    # masked = np.ma.masked_where(hst_seg.data.cpu()[0, slice_n].squeeze() == 0, hst_seg.data.cpu()[0, slice_n].squeeze())
    # plt.imshow(masked, cmap=cm,aspect=1.0 / aspect, alpha=0.5)
    # plt.axis('off')
    # plt.gca().invert_yaxis()
    # plt.gca().patch.set_facecolor([0, 0, 0, 0])
    # plt.savefig(f'{out_dir}/day3_shaded_hist.png', dpi=600, bbox_inches='tight', pad_inches=0, transparent=True)
    # #
    # circle_mask = create_circular_mask(112, 533, center=[280, 40], radius=50)
    # outside_FOV = log_ctd.data[0, slice_n].cpu().numpy() > 0
    # ctd_mask = np.logical_and(outside_FOV, circle_mask == 1)
    # ctd_slice = torch.exp(log_ctd.data[0, slice_n].cpu())
    # ctd_mask = np.logical_and(ctd_slice > 10.0, circle_mask == 1)
    # masked_thermal = np.ma.masked_where(ctd_mask == 0.0, ctd_slice.numpy()).squeeze()
    # plt.figure()
    # # plt.imshow(t1_nc.data.cpu()[0, slice_n].squeeze(), aspect=1.0 / aspect, cmap='gray')
    # plt.imshow(masked_thermal, aspect=1.0 / aspect, cmap='jet', vmin=0.5, vmax=240)
    # plt.gca().patch.set_facecolor([0, 0, 0, 0])
    # plt.gca().invert_yaxis()
    # plt.axis('off')
    # # plt.savefig(f'{out_dir}/day0_ctd_no_cmap.png', dpi=600, bbox_inches='tight', pad_inches=0, transparent=True)
    # plt.colorbar()
    # # plt.savefig(f'{out_dir}/day0_ctd_cmap.png', dpi=600, bbox_inches='tight', pad_inches=0, transparent=True)
    # slice_im = t1_nc.data.cpu()[0, slice_n].squeeze()
    # zero_slice = np.zeros_like(slice_im)
    # masked_slice = np.ma.masked_where(zero_slice == 0.0, zero_slice).squeeze()
    # plt.figure()
    # plt.imshow(masked_slice.squeeze(), aspect=1.0 / aspect, cmap='gray')
    # npv_slice = log_ctd.data.cpu()[0, slice_n].squeeze()
    # npv_contours = measure.find_contours(npv_slice.data.squeeze().cpu().numpy() * circle_mask, np.log(240))
    # for contour in npv_contours:
    #     plt.plot(contour[:, 1], contour[:, 0], color='red', linewidth=1.8)
    # plt.axis('off')
    # plt.gca().invert_yaxis()
    # plt.gca().patch.set_facecolor([0, 0, 0, 0])
    # plt.savefig(f'{out_dir}/day0_ctd_contour.png', dpi=600, bbox_inches='tight', pad_inches=0, transparent=True)
    # circle_mask = create_circular_mask(112, 533, center=[280, 40], radius=50)
    # for s in range(140, 201):
    for s in range(70, 150):
        # for s in range(100, 180):
        # Extract the slice
        im_slice = t1_nc[:, s].squeeze().cpu()
        # seg_slice = npv_seg[:, s].squeeze().cpu()
        seg_slice = log_ctd[:, s].squeeze().cpu()
        ext_slice = hst_seg[:, s].squeeze().cpu()
        #

        # ctd_mask = np.logical_and(seg_slice > 2.3, circle_mask == 1)
        # seg_slice = seg_slice * ctd_mask
        seg_slice = (seg_slice >= np.log(240)).float()
        # im_slice = im_slice[:, 80:-80]
        # seg_slice = seg_slice[:, 80:-80]
        # ext_slice = ext_slice[:, 80:-80]

        # plt.figure()
        # plt.imshow(im_slice, cmap='gray', aspect=1.0 / aspect, interpolation='nearest')
        # plt.axis('off')
        # plt.show()
        # plt.gca().invert_yaxis()
        # plt.savefig(f'{frame_dir}/Images/{s:03d}_image.png', dpi=600, bbox_inches='tight', pad_inches=0)
        #
        # plt.close('all')

        generate_slice(s,
                       im_slice,
                       seg_slice,
                       frame_dir,
                       aspect,
                       color='red',
                       extra=ext_slice)
        # generate_slice(s, im_slice, seg_slice, frame_dir, aspect, color='red', extra=ext_slice)

        print(f'Done with slice {s}/{int(images.size[0])}')