示例#1
0
def load_patch(patch_ID, mouse, channel):
    
    filename = 'patchvolume_' + str(patch_ID) + '.nii'
    path_to_patchdata = HEAVY_DATAPATH + '/' + mouse + '/patchvolumes/' + channel + '/' + filename

    try:
        patch = filehandling.readNifti(path_to_patchdata)
    except FileNotFoundError: 
        print("Nifti-file " + filename + " doesn't exist")
        return None
    
    return patch
示例#2
0
def load_patch(patch_id):
    global region, patch, segmentation, volume, volume_vis, max_mID, metastases, DIMmetastases, removed_metastases, main_n_added, volume_autofluo
    patch = next((p for p in region['patches'] if p["id"] == patch_id))
    segmentation    = p_leo.load_segmentation(dataset,patch_id,load_partial=False)
    volume_autofluo = filehandling.readNifti(path_autofluo + 'patchvolume_' + str(patch_id))
    volume          = filehandling.readNifti(path_patches  + 'patchvolume_' + str(patch_id))
    volume_vis      = np.clip(volume, 0, signalcap) / signalcap # Cap & scaling for visualization
    
    if(patch_id == 9999):
        volume = volume[:,:,:,0]
        volume_vis = volume_vis[:,:,:,0]
        patch = {}
        patch['id'] = patch_id
        segmentation['patch_id'] = patch_id
        region = {}
        region['partitioning'] = {}
        region['partitioning']['patch_overlap'] = 50
    
    max_mID = segmentation['max_mID']
    metastases = segmentation['metastases']
    DIMmetastases = segmentation['dim_metastases'] if ('dim_metastases' in segmentation.keys()) else []
    removed_metastases = segmentation['removed_metastases']
    main_n_added = len(list((m for m in metastases if m['evaluation']['manually_added'] == True)))
示例#3
0
def overview_update_plot():
    global overview_ax1, overview_ax2, overview_ax3, overview_ax4, overview_ax5
    plt.figure(num=overview_fig.number)

    ds = region['thumbnails']['downsampling']
    [dy, dx, dz] = (np.asarray(region['partitioning']['patch_size']) - region['partitioning']['patch_overlap']) * ds
    
    overview_ax1.clear()
    overview_ax1.set_title('Top view full volume', fontsize=fs[2], fontweight='bold')
    plotting.intensity(np.max(region['thumbnails']['MaxProjections_Z'],2),ahandle=overview_ax1,cap=signalcap)
    overview_ax1.add_patch(patches.Rectangle((dx*next_patch['patchstep'][1],dy*next_patch['patchstep'][0]),dx,dy,linewidth=2,fill=False,edgecolor='red'))
    overview_ax1.set_xticks([])
    overview_ax1.set_yticks([])
    overview_ax1.set_ylabel('Y-Axis')
    overview_ax1.set_xlabel('X-Axis')
    
    overview_ax2.clear()
    overview_ax2.set_title('Side view of full volume', fontsize=fs[2], fontweight='bold')
    plotting.intensity(np.max(region['thumbnails']['MaxProjections_X'],2),ahandle=overview_ax2,cap=signalcap)
    overview_ax2.add_patch(patches.Rectangle((dz*next_patch['patchstep'][2],dy*next_patch['patchstep'][0]),dz,dy,linewidth=2,fill=False,edgecolor='red'))
    overview_ax2.set_xticks([])
    overview_ax2.set_yticks([])
    overview_ax2.set_xlabel('Z-Axis')
    
    overview_ax3.clear()
    overview_ax3.set_title('Top view of selected slice', fontsize=fs[2], fontweight='bold')
    plotting.intensity(region['thumbnails']['MaxProjections_Z'][:,:,next_patch['patchstep'][2]],ahandle=overview_ax3,cap=signalcap)
    overview_ax3.add_patch(patches.Rectangle((dx*next_patch['patchstep'][1],dy*next_patch['patchstep'][0]),dx,dy,linewidth=2,fill=False,edgecolor='red'))
    overview_ax3.set_xticks([])
    overview_ax3.set_yticks([])
    overview_ax3.set_xlabel('X-Axis')
    
    overview_ax4.clear()
    Z0 = next_patch['offset'][2]
    Z1 = next_patch['offset'][2] + (next_patch['boundingbox'][2]-region['partitioning']['patch_overlap'])
    X = int(next_patch['offset'][1] + 0.5* (next_patch['boundingbox'][1]-region['partitioning']['patch_overlap']))
    Y = int(next_patch['offset'][0] + 0.5* (next_patch['boundingbox'][0]-region['partitioning']['patch_overlap']))
    overview_text = 'The core body is partitioned into '+str(len(region['patches']))+' patches (x='+str(region['partitioning']['patches_per_dim'][1])+'; y='+str(region['partitioning']['patches_per_dim'][0])+'; z='+str(region['partitioning']['patches_per_dim'][2])+'). \n\nThe segmentations of '+str(len(segs_completed))+' patches ('+str(int(100*len(segs_completed)/len(region['patches'])))+'%) have been evaluated, \n'+str(len(segs_outstanding))+' are still outstanding. \n\nCurrent patch is #'+str(next_patch['id'])+' (x='+str(next_patch['patchstep'][1])+'; y='+str(next_patch['patchstep'][0])+'; z='+str(next_patch['patchstep'][2])+'). \n\nIn the full volume (i.e. if you open it in Fiji), this patch is \nbetween slices '+str(Z0)+' and '+str(Z1)+' and its centerpoint \nis at x='+str(X)+' and y='+str(Y)+'.'
    overview_ax4.text(0,0.2,overview_text, fontsize=fs[2])
    overview_ax4.axis('off')
    
    overview_ax5.clear()
    overview_ax5.set_title('Preview of current patch (#'+str(next_patch['id'])+') - open to see labels', fontsize=fs[2], style='italic')
    pvol = filehandling.readNifti(path_patches + 'patchvolume_' + str(next_patch['id']))
    plotting.intensity(np.max(pvol[0:int(dy/ds),0:int(dx/ds),0:int(dz/ds)],2),ahandle=overview_ax5,cap=signalcap)

    plt.pause(0.01)
    plt.draw()
示例#4
0
def load_segmentation(dataset, pid, load_partial, THR_dim=200):
    '''
    segmentation = load_segmentation(dataset,pid,load_partial,THR_dim=200)
    
    Not only loads segmentation file for desired patch, but also includes all (dim) metastases
    that belong to adjacent patches if they partially overlap with this patch. 
    
    For those cases, only the overlapping part of the metastasis is included, i.e. this function 
    may NOT BE USED to derive statistical information on the metastases as this will be false 
    for exactly those partial metastases.
    
    Also, if the part within the patch is small (less than 20% of total volume) or dim, it will
    only be included as a "dim" metastasis, i.e. detection will not be rewarded and missing it
    will not be punished; these metastases will have to be detected from the patch in which the
    majority of its volume is in
    
    Inputs:
     - dataset: string specifying dataset ("F15")
     - pid: integer for patch ID to be loaded
     - load_partial: boolean whether or not to load partially overlapping blobs from surrounding patches
     - THR_dim: threshold to check whether partial blobs are now considered dim because brighter parts are in other patch
    '''
    seg = filehandling.pload(BASEP + 'data/' + dataset +
                             '/segmentations/segmentation_patch_' + str(pid))
    if (os.path.isfile('/mnt/C286054386053985/oschoppe/F15/patchvolume_' +
                       str(pid) + '.nii') == False):
        print(
            'WARNING: cannot load local patch files and thus, cannot consider partial blobs properly.'
        )
        print(
            '--> function load_segmentation() will be called with load_partial=False instead'
        )
        print('ALTERED PATHS IN p_leo2 AND ALL HELPER FUNCTIONS!')
        load_partial = False
    if (load_partial):
        region = filehandling.pload(BASEP + 'data/' + dataset + '/region')
        [maxy, maxx,
         maxz] = np.asarray(region['partitioning']['patch_size']
                            ) - region['partitioning']['patch_overlap']
        [y0, x0, z0] = region['patches'][pid]['patchstep']
        cancervol = filehandling.readNifti(
            '/mnt/C286054386053985/oschoppe/F15/patchvolume_' + str(pid))
        add_part_metastases = []
        add_part_dim_metastases = []
        # Go through neighboring patches whose buffer zones overlap with patch
        for dy in [-1, 0]:
            for dx in [-1, 0]:
                for dz in [-1, 0]:
                    [y, x, z] = [y0 + dy, x0 + dx, z0 + dz]
                    if ((y >= 0 and x >= 0 and z >= 0)
                            and ((y == y0 and x == x0 and z == z0) is False)):
                        npid = dataconversions.filter_dicts(
                            region['patches'], 'patchstep', [y, x, z])[0]['id']
                        nseg = filehandling.pload(
                            BASEP + 'data/' + dataset +
                            '/segmentations/segmentation_patch_' + str(npid))
                        # check whether any metastases overlap with patch
                        dim_metastases = [] if (
                            'dim_metastases'
                            not in nseg.keys()) else nseg['dim_metastases']
                        for m in nseg['metastases'] + dim_metastases:
                            abs_bb = m['offset'] + m['boundingbox']
                            if ((abs_bb[0] >= (-1) * dy * maxy)
                                    and (abs_bb[1] >= (-1) * dx * maxx)
                                    and (abs_bb[2] >= (-1) * dz * maxz)):
                                # if so, then include THOSE points WITHIN the patch & adjust coordinate system to new patch
                                patchstep_offset = np.multiply(
                                    [maxy, maxx, maxz], [dy, dx, dz])
                                shifted_points = m['points'] + patchstep_offset
                                filtered_points = shifted_points[
                                    np.min(shifted_points, axis=1) >=
                                    0]  # only take points fully within patch
                                if (len(filtered_points) > 0):
                                    # characterize new partial blob
                                    m_partial = {}
                                    m_partial['id'] = 100 * npid + m['id']
                                    m_partial[
                                        'points'] = filtered_points.tolist()
                                    m_partial = blobanalysis.characterize_blob(
                                        m_partial)  # ~ 0.1 s
                                    m_partial = characterize_metastasis(
                                        m_partial,
                                        cancervol,
                                        min_padding=25,
                                        otherblobs=seg['metastases']
                                    )  # ~ 0.01 s
                                    # add to main list if NOT dim and at least 20% within patch
                                    if (m_partial['characterization']['maxFG']
                                            > THR_dim and m_partial['volume']
                                            >= 0.2 * m['volume']):
                                        m_partial[
                                            'INFO'] = 'Partial, but substantial metastases from adjacent patch #' + str(
                                                npid)
                                        add_part_metastases.append(m_partial)
                                    else:
                                        m_partial['evaluation'][
                                            'flag_dim'] = True
                                        m_partial[
                                            'INFO'] = 'Partial, but dim/very small part of metastases from adjacent patch #' + str(
                                                npid)
                                        add_part_dim_metastases.append(
                                            m_partial)
        seg['metastases'] += add_part_metastases
        if ('dim_metastases' in seg.keys()):
            seg['dim_metastases'] += add_part_dim_metastases

    return seg
示例#5
0
# Standard python libraries
import numpy as np
import matplotlib.pyplot as plt

BASEP = ROOTP + 'Leo/'  # base path for project folder

#%% Define parameters

region = filehandling.pload(BASEP + 'data/F15/region.pickledump')
segmentation = filehandling.pload(BASEP + 'data/F15/segmentation.pickledump')
segmentation_patch_515 = filehandling.pload(
    BASEP + 'data/F15/segmentations/segmentation_patch_515.pickledump')

tumor_volume_515 = filehandling.readNifti(
    ROOTP + 'LocalData/F15/C02_tumorBoost/patchvolume_515.nii'
)  # we're reading in a .nii file, so it's real image data, not just metadata

#%% Main code

# print dictionary in structured format to console

print("--- Region (meta data for patch locations):")
plotting.print_dict(region)
print("\n\n")

print("--- Segmentation (aggregated list of metastases across all patches):")
plotting.print_dict(segmentation)

print("\n\n")
print("--- Single segmentation (list of metastases for one patch):")
bbz = int(region['partitioning']['cropping_boundingbox'][2] * thumbnail_ds)
mpy = np.zeros((bbx, bbz, region['partitioning']['patches_per_dim'][0]),
               np.float32)
mpx = np.zeros((bby, bbz, region['partitioning']['patches_per_dim'][1]),
               np.float32)
mpz = np.zeros((bby, bbx, region['partitioning']['patches_per_dim'][2]),
               np.float32)
dy = int((region['partitioning']['patch_size'][0] -
          region['partitioning']['patch_overlap']) * thumbnail_ds)
dx = int((region['partitioning']['patch_size'][1] -
          region['partitioning']['patch_overlap']) * thumbnail_ds)
dz = int((region['partitioning']['patch_size'][2] -
          region['partitioning']['patch_overlap']) * thumbnail_ds)
for patch in region['patches']:
    print('Creating thumbnail for patch #' + str(patch['id']))
    pvol = filehandling.readNifti(localfolder + 'patchvolume_' +
                                  str(patch['id']))
    pvol = pvol[0:int(dy / thumbnail_ds), 0:int(dx / thumbnail_ds),
                0:int(dz / thumbnail_ds)]
    s = patch['patchstep']
    mpy[s[1] * dx:(s[1] + 1) * dx, s[2] * dz:(s[2] + 1) * dz,
        s[0]] = imresize(np.max(pvol, 0), thumbnail_ds, mode='F')
    mpx[s[0] * dy:(s[0] + 1) * dy, s[2] * dz:(s[2] + 1) * dz,
        s[1]] = imresize(np.max(pvol, 1), thumbnail_ds, mode='F')
    mpz[s[0] * dy:(s[0] + 1) * dy, s[1] * dx:(s[1] + 1) * dx,
        s[2]] = imresize(np.max(pvol, 2), thumbnail_ds, mode='F')
    mpy[s[1] * dx, :, s[0]] = mpy[:, s[2] * dz, s[0]] = 0
    mpx[s[0] * dy, :, s[1]] = mpx[:, s[2] * dz, s[1]] = 0
    mpz[s[0] * dy, :, s[2]] = mpz[:, s[1] * dx, s[2]] = 0

# Update and save region overview to file
region['thumbnails'] = {}
示例#7
0

#%% Step 2) For each metastasis, add all relevant meta information

for m, metastasis in enumerate(segmentation['metastases']): # double loop as this will be needed for upcoming computations
    print('Loop 1/2: Adding information for metastasis #' + str(metastasis['global_id']))
    # add global location information to metastasis
    segmentation['metastases'][m]['location'] = {}
    p_offset = np.asarray(region['patches'][metastasis['patch_id']]['offset'])
    segmentation['metastases'][m]['location']['offset'] = (p_offset + metastasis['offset']).tolist()
    segmentation['metastases'][m]['location']['center'] = (p_offset + metastasis['offset'] + metastasis['CoM']).tolist()
    
    # Add info from drug channel: are metastases significantly targeted?
    #  --> Yes, if mean(FG) significantly above 1.5*mean(BG)
    if(dataset == 'F15'):
        drugvol = filehandling.readNifti(pathDrug + 'patchvolume_' + str(metastasis['patch_id']) + '.nii')
        otherblobs = dataconversions.filter_dicts(segmentation['metastases'],'patch_id',metastasis['patch_id'])
        metastasis = p_leo.characterize_drugtargeting(metastasis,drugvol,min_padding=25,thr=1.5,otherblobs=otherblobs)

for m, metastasis in enumerate(segmentation['metastases']):
    print('Loop 2/2: Adding information for metastasis #' + str(metastasis['global_id']))
    
    # compute distance to nearest neighbor metastasis
    segmentation['metastases'][m]['location']['distNN'] = 99999
    segmentation['metastases'][m]['location']['distNNtargeted'] = 99999
    segmentation['metastases'][m]['location']['distNNuntargeted'] = 99999
    for neighbor in segmentation['metastases']:
        dist = blobanalysis.point_dist(metastasis['location']['center'],neighbor['location']['center'])
        if(metastasis['global_id'] is not neighbor['global_id']):
            segmentation['metastases'][m]['location']['distNN'] = np.min([segmentation['metastases'][m]['location']['distNN'],dist])
            if(dataset == 'F15'):