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
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)))
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()
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
# 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'] = {}
#%% 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'):