def __init__(self, path, image=None): """Open ROI (.roi) or list of ROIs (.zip) using ijroi modules INPUT: Path to ROI file image: Defines the path to an image associated with the ROIs. Optional. Can be added later""" from read_roi import read_roi_file, read_roi_zip import pims # Import ROI list if path.split('.')[-1] == "zip": self.rois = read_roi_zip(path) # imports a labeled dict elif path.split('.')[-1] == "roi": self.rois = read_roi_file(path) # import single ROI else: # no file extension provided try: self.rois = read_roi_zip(path + '.zip') # imports a labeled dict print('importing list of rois') except FileNotFoundError: # .roi file, not .zip file self.rois = read_roi_file(path + '.roi') # import single ROI print("Opening single ROI...") self.keys = list( self.rois.keys()) # get list of ROI names for referencing in Dict self.attach_image(image) # attach image if specified return
def plot_clusters_in_roi(roi_path, pixel_size, cluster_list, noise=None, save=False, filename=None, show_plot=True, new_figure=True, cluster_marker_size=4): filename, ext = os.path.splitext(roi_path) print(ext) if 'zip' in ext: rois = read_roi_zip(roi_path) else: rois = read_roi_file(roi_path) for roi_id, roi in rois.items(): for k, v in roi.items(): if not isinstance(v, str): roi[k] = float(v) * pixel_size plot_optics_clusters(cluster_list, noise=noise, save=False, filename=None, show_plot=True, new_figure=True, cluster_marker_size=4, roi=roi)
def get_rect_coordinates_from_roi(fname): """ This function returns the coordinates from a rectangular region of interest defined in a .roi file generated by ImageJ / Fiji. N.B.: indexing starts from 0. Incremet rowmax and col_max + 1 to crop an image, for example: crop = img[rowmin:(rowmax+1), colmin:(colmax+1)] Parameters ---------- fname : str String defining the path or the name of the Image ROI file. Returns ------- rowmin : int The minimum row coordinate. rowmax : int The maximum row coordinate. colmin : int The minimum column coordinate. colmax : int The maximum column coordinate. """ # file name check if (type(fname) is not str): logs.error('File name must be a string.') raise TypeError('File name must be a string.') else: if not (fname.endswith('.roi')): logs.warning('File extension shold be .roi') # read roi file roi = read_roi_file(fname) # convert keys to list l = list(roi.keys()) # extract coordinates and length height = roi[l[0]]['height'] width = roi[l[0]]['width'] top = roi[l[0]]['top'] left = roi[l[0]]['left'] rowmin = int(top) rowmax = int(top + height - 1) colmin = int(left) colmax = int(left + width - 1) # log infos logs.info('ROI file succesfully read: %s', fname) return rowmin, rowmax, colmin, colmax
def get_roi(name): listing = s3_client.list_objects(Bucket=BUCKET, Prefix=image_path(name)) result = [] for file in listing["Contents"]: if (file["Key"].endswith('.roi')): print(file["Key"]) tmp_file = '/tmp/roi_file_tmp.roi' with open(tmp_file, 'wb') as f: s3_client.download_fileobj(BUCKET, file["Key"], f) rois = read_roi_file(tmp_file) result.append(rois) return jsonify(result)
def read_roi_and_get_mask(roi_paths, mask_names, root_data_folder, mask_folder, im_type, image_name, shape): #Create Black image to put the masks on: mask_img = np.zeros(shape, np.uint8) for i, (roi_path, mask_name) in enumerate(zip(roi_paths, mask_names)): #Get the roi roi = read_roi_file(roi_path)[mask_name] #Create the mask mask_img = obtain_mask(mask_img, roi) #Define the path to be written to mask_path = root_data_folder + "/" + mask_folder + "/" + image_name + "_" + im_type + ".jpg" return mask_path, mask_img
def _load_profiles_from_imagej(self, fn, constant_slice=None, gui=True): """ Read line profiles from Fiji/ImageJ. Parameters ---------- fn : str Filename containing line profiles. constant_slice : int Set slice to a constant value. Useful if ImageJ output is inconsistent. gui: bool flag to update names / send signals to update the gui profile list. """ import zipfile try: import read_roi except (ImportError): raise ImportError( 'Please install the read_roi package (https://pypi.org/project/read-roi/).' ) try: imagej_rois = read_roi.read_roi_zip(fn) except (zipfile.BadZipFile): imagej_rois = read_roi.read_roi_file(fn) for key in imagej_rois.keys(): roi = imagej_rois[key] # Check for a slice val if constant_slice is None: try: slice_val = roi['position'] - 1 except KeyError: slice_val = 0 else: slice_val = constant_slice # x, y transposed in Fiji/ImageJ # Position is 1-indexed in Fiji/ImageJ self.add_line_profile(rois.LineProfile(roi['y1'], roi['x1'], roi['y2'], roi['x2'], slice=slice_val, width=roi['width'], identifier=roi['name'], image_name=self.image_name), update=False) if gui: self.update_names(relabel=True) self._on_list_changed()
def batch_stats(folder, conditions, use_roi=False): for filename in os.listdir(folder): if filename.endswith('xlsx'): stats_path = os.path.join(folder, filename) basename = os.path.splitext(filename)[0] if use_roi: roi_zip_path = os.path.join(folder, basename + '_roiset.zip') roi_file_path = os.path.join(folder, basename + '_roiset.roi') if os.path.exists(roi_zip_path): rois = read_roi_zip(roi_zip_path) elif os.path.exists(roi_file_path): rois = read_roi_file(roi_file_path) else: raise ValueError(("No ImageJ roi file exists -" "you should put the file in the same" "directory as the data")) stats = [] for roi in rois.keys(): stats.append(import_cluster_stats(stats_path), sheetname=roi) stats_df = pd.concat(stats) else: stats_df = import_cluster_stats(stats_path) fnames = [f for f in listdir(folder) if isfile(join(folder, f))] outpath = os.path.join(folder, 'cluster_statistics_test.xlsx') for condition in conditions: condition_fnames = [ fname for fname in fnames if condition in fname ] cluster_stats = [] for cf in condition_fnames: cluster_stats.append(stats[cf]) cddf = pd.DataFrame(condition_fnames) cddf.columns = ['filename'] csdf = pd.concat(cluster_stats, axis=0) data = pd.concat([cddf, csdf.reset_index(drop=True)], axis=1) statistics.write_stats(stats_path, data, condition)
def voronoi(locs_path, roi_path=None, pixel_size=16.0, density_factor=2, min_size=5, show_plot=True, verbose=True): if locs_path.endswith('csv'): # Thunderstorm locs_df = pd.read_csv(locs_path) if roi_path: if roi_path.endswith('zip'): rois = read_roi_zip(roi_path) elif roi_path.endswith('roi'): rois = read_roi_file(roi_path) else: raise ValueError( ("No ImageJ roi file exists -" "you should put the file in the same directory" "as the data and make sure it has the same base" "filename as the localisations.")) else: # use all the localisations but mimic the rois dict data structure dx = locs_df['x [nm]'].max() - locs_df['x [nm]'].min() dy = locs_df['y [nm]'].max() - locs_df['y [nm]'].min() rois = {'image': {'locs': locs_df, 'width': dx, 'height': dy}} for roi_id, roi in rois.items(): vor = build_voronoi(rois[roi_id]['locs'], show_plot=False, verbose=verbose) clusters = voronoi_clustering(vor, density_factor, min_size) if show_plot: plot_voronoi_diagram(clusters['voronoi'], locs_df=clusters['locs']) return clusters else: raise ValueError( "This can only handle data from Thunderstorm at present")
def get_locs_in_rois(ijroi_path, roi_scale, locs): if ijroi_path.endswith('zip'): rois = read_roi_zip(ijroi_path) elif ijroi_path.endswith('roi'): rois = read_roi_file(ijroi_path) else: raise ValueError("No ImageJ roi file exists") for _, roi in rois.items(): for k, v in roi.items(): if not isinstance(v, str): roi[k] = float(v) * roi_scale roi['locs'] = locs[(locs['x'] > roi['left']) & (locs['x'] < roi['left'] + roi['width']) & (locs['y'] > roi['top']) & (locs['y'] < roi['top'] + roi['height'])].reset_index(drop=True) return rois
def voronoi_segmentation(locs_path, roi_path=None, segment_rois=False, pixel_size=16.0, monte_carlo=True, object_density_factor=2, object_min_samples=3, cluster_density_factor=20, cluster_min_samples=3, num_rois=5, roi_size=7000.0, show_plot=False): """ This uses a Monte Carlo simulation to predict which localisations are no better than a random distribution. This is used to do a first pass segmentation of 'objects' after which 'clusters' are located in those in those objects based on local density and a minimum number of objects. """ # read in the complete localisations if locs_path.endswith('csv'): # Thunderstorm locs = pd.read_csv(locs_path) else: raise ValueError( "This can only handle data from Thunderstorm at present") if roi_path: if roi_path.endswith('zip'): input_rois = read_roi_zip(roi_path) elif roi_path.endswith('roi'): input_rois = read_roi_file(roi_path) else: raise ValueError(("No ImageJ roi file exists -" "you should put the file in the same directory" "as the data and make sure it has the same base" "filename as the localisations.")) # add the localisations to the rois dict rois = roi_coords(locs, input_rois, pixel_size) else: # generate a random set of rois rois = random_rois(locs, num_rois, roi_size) if monte_carlo: intersection = 0.0 for roi_id, roi in rois.items(): print("Monte Carlo simulation in ROI {0}".format(roi_id)) # pass the locs DataFrame and roi dict to voronoi_montecarlo rmc = voronoi_montecarlo(roi, show_plot=show_plot) intersection += rmc['intersection'] # always use the average intersection intersection /= float(len(rois)) thresh = 1.0 / intersection # density factor for each roi (whether random roi or IJ roi) density_factor = {} for roi_id, roi in rois.items(): if monte_carlo: density_factor[roi_id] = thresh / density(roi['locs']) else: density_factor[roi_id] = object_density_factor if not segment_rois: # use all the localisations but mimic the rois dict data structure rois = {'image': {'locs': locs}} # and reset the density_factor for the whole image density_factor = {} if monte_carlo: density_factor['image'] = thresh / density(rois['image']['locs']) else: density_factor['image'] = object_density_factor print("density_factor: {}".format(density_factor)) # now loop over the rois data structure for roi_id, roi in rois.items(): # build the voronoi diagram roi_locs = roi['locs'] roi_locs['object_id'] = -1 roi_locs['cluster_id'] = -1 vor = build_voronoi(roi_locs) if monte_carlo: print("intersection: {0}".format(intersection)) print("density threshold: {0}".format(thresh)) print("density_factor: {}".format(density_factor[roi_id])) objs = voronoi_clustering(vor, density_factor[roi_id], object_min_samples, cluster_column='object_id') # write the objects to the original localisations data structure obj_locs = objs['locs'] roi_locs.loc[roi_locs.object_id.isin(obj_locs.object_id), ['object_id']] = ( obj_locs[obj_locs['object_id'] > -1]['object_id']) # retain only the objects that are 'clustered' filtered = obj_locs[obj_locs['object_id'] != -1] # prepare the data structure for re-clustering data = {'voronoi': vor['voronoi'], 'locs': filtered} # set parameters and find clusters in objects n_locs = len(roi_locs.index) clusters = voronoi_clustering(data, cluster_density_factor, cluster_min_samples, cluster_column='cluster_id', num_locs=n_locs) # write the clusters to the original localisations data structure clust_locs = clusters['locs'] roi_locs.loc[roi_locs.cluster_id.isin(clust_locs.cluster_id), ['cluster_id']] = (clust_locs[ clust_locs['cluster_id'] > -1]['cluster_id']) if show_plot: cfig = plot_voronoi_diagram(clusters['voronoi'], locs_df=clusters['locs'], cluster_column='cluster_id') plot_cluster_polygons(objs['locs'], figure=cfig, cluster_column='object_id') plt.show() # fill nan values before returning roi_locs[['object_id', 'cluster_id']] = roi_locs[['object_id', 'cluster_id']].fillna(value=-1) roi['locs'] = roi_locs return rois
from read_roi import read_roi_file import numpy as np from PIL import Image, ImageDraw from matplotlib import pyplot as plt width = 84 height = 128 ROIFilename = '15_ADC' # read roi file roi_object = read_roi_file(ROIFilename + '.roi') roi_temp = roi_object[ROIFilename] # make polygon polygon = [] for x, y in zip(roi_temp['x'], roi_temp['y']): polygon.append(x) polygon.append(y) # make mask img = Image.new('L', (width, height), 0) ImageDraw.Draw(img).polygon(polygon, outline=1, fill=1) mask = np.array(img) # display plt.imshow(mask, cmap='gray') plt.show()
def calc_nuclear_enrichment(FQ_file, binsHist): ## Get folder drive, path_and_file = os.path.splitdrive(FQ_file) path_results, file_results = os.path.split(path_and_file) # ************************************************************************* # Load nuclear outline # Generate binary masks for a selected data-set binaryGen = maskGenerator.BinaryMaskGenerator(erose_size=5, obj_size_rem=500, save_indiv=True, progress_callback=None) ## Import annotations for nuclei path_annot = os.path.join(drive, path_results, 'zstack_segmentation') folderImporter = annotationImporter.FolderImporter( channels={'nuclei': 'C4-'}, data_category={'roi': ''}, annot_ext='__RoiSet.zip', progress_callback=None) annotDict = folderImporter.load(path_annot) print('average roi size:', annotDict['roi_size']) # The generate function uses as an input the sub-dictionary for one data-category and one channel annotatFiles = annotDict['roi']['nuclei'] mask_dict_nuclei = binaryGen.generate(annotatFiles) keys_delete = [] for k, v in annotatFiles.items(): # Make sure that key in present in mask, otherwise delete if k in mask_dict_nuclei: v.update(mask_dict_nuclei[k]) else: keys_delete.append(k) # ************************************************************************* # Load embryo outline file_embryo = os.path.join(drive, path_results, 'embryo_contour.roi') # Conver dictionary & get size of ROIS roi_import = read_roi_file(file_embryo) roi_dict = {} roi_dict['embryo'] = {} roi_dict['embryo']['type'] = roi_import['embryo_contour']['type'] roi_dict['embryo']['pos'] = np.column_stack( (roi_import['embryo_contour']['y'], roi_import['embryo_contour']['x'])) # Assemble structure to call mask generator image_size = annotatFiles.values().__iter__().__next__()['image'].shape image_fake = np.zeros(image_size, dtype=np.uint8) annotat_files_embryo = {} annotat_files_embryo['embryo_contour'] = {} annotat_files_embryo['embryo_contour']['roi'] = roi_dict annotat_files_embryo['embryo_contour']['image'] = image_fake mask_dict_embryo = binaryGen.generate(annotat_files_embryo) mask_embryo = mask_dict_embryo['embryo_contour']['mask_fill'] # ************************************************************************* # Load and analyze FQ results fq_dict = FQtoolbox.read_FQ_matlab(file_load) spots_all = FQtoolbox.get_rna(fq_dict) # Z position in pixel Zrna = np.divide(spots_all[:, [2]], fq_dict['settings']['microscope']['pix_z']).astype(int) # Other parameters for calculation dist_membr_RNA = np.array([]) dist_membr_pix = np.array([]) idx = 0 # Loop over all z-slices print(' == Loop over slices') for idx_file, (k_annot, v_annot) in enumerate(annotatFiles.items()): print(f'Slice: {k_annot}') # Get Z coordinate m = re.search('.*_Z([0-9]*)\.tif', k_annot) Zmask = int(m.group(1)) # Check if outside of specified z range if Zrange is not None: if (Zmask < Zrange[0]) or (Zmask > Zrange[1]): print(f'Z-slice outside of specified range: {Zmask}') continue # Get z-range for loop Zloop = np.logical_and(Zrna <= Zmask + dZ, Zrna >= Zmask - dZ).flatten() Zloop = (Zrna == Zmask).flatten() spots_loop = spots_all[Zloop, :] spots_loop_XY = np.divide( spots_loop[:, [0, 1]], fq_dict['settings']['microscope']['pix_xy']).astype(int) # Distance transform dist_nuc_outside = ndimage.distance_transform_edt( ~v_annot['mask_fill']) dist_nuc_inside = ndimage.distance_transform_edt( v_annot['mask_fill']) # Negate mask dist_nuc = dist_nuc_outside - dist_nuc_inside # Indices have to be inversed to access array dist_nuc_RNA_loop = dist_nuc[spots_loop_XY[:, 0], spots_loop_XY[:, 1]] # Get distance from membrane for all pixel in the cell dist_membr_pix_loop = dist_nuc[mask_embryo.astype(bool)] # Save values if idx == 0: dist_membr_RNA = np.copy(dist_nuc_RNA_loop) dist_membr_pix = np.copy(dist_membr_pix_loop) else: dist_membr_RNA = np.append(dist_membr_RNA, dist_nuc_RNA_loop, axis=0) dist_membr_pix = np.append(dist_membr_pix, dist_membr_pix_loop, axis=0) idx += 1 # ************************************************************************* # Load and analyze FQ results xTicks = binsHist[:-1] width = 0.9 * np.diff(binsHist) width_full = np.diff(binsHist) center = (binsHist[:-1] + binsHist[1:]) / 2 histRNA_all, bins = np.histogram(dist_membr_RNA, binsHist, density=False) histPIX_all, bins = np.histogram(dist_membr_pix, binsHist, density=False) histRNA_norm = np.divide(histRNA_all, histPIX_all) counts_total = np.nansum(np.multiply(histRNA_norm, width_full)) histRNA_norm = np.divide(histRNA_norm, counts_total) fig1, ax = plt.subplots(3, 1) ax[0].bar(center, histRNA_all, align='center', width=width) ax[0].set_xlabel('Dist to nuc') ax[0].set_ylabel('# RNAs') ax[0].set_xticks(xTicks) ax[0].set_xticklabels(xTicks.astype(int)) ax[1].bar(center, histPIX_all, align='center', width=width) ax[1].set_xlabel('Dist to nuc') ax[1].set_ylabel('# pixels') ax[1].set_xticks(xTicks) ax[1].set_xticklabels(xTicks.astype(int)) ax[2].bar(center, histRNA_norm, align='center', width=width) ax[2].set_xlabel('Distance to nuc') ax[2].set_ylabel('RNA counts [a.u.]') ax[2].set_xticks(xTicks) ax[2].set_xticklabels(xTicks.astype(int)) ax[0].title.set_text('RNAs') ax[1].title.set_text('All pixel') ax[2].title.set_text('RNA renormalized with pixels') plt.tight_layout()
keys_delete = [] for k, v in annotatFiles.items(): # Make sure that key in present in mask, otherwise delete if k in maskDict: v.update(maskDict[k]) else: keys_delete.append(k) #%% Determine embryo outline from read_roi import read_roi_file file_embryo = os.path.join(drive, path_results, 'embryo_contour.roi') # Conver dictionary & get size of ROIS roi_import = read_roi_file(file_embryo) roi_dict = {} roi_dict['embryo'] = {} roi_dict['embryo']['type'] = roi_import['embryo_contour']['type'] roi_dict['embryo']['pos'] = np.column_stack( (roi_import['embryo_contour']['y'], roi_import['embryo_contour']['x'])) # Assemble structure to call mask generator image_size = annotatFiles.values().__iter__().__next__()['image'].shape image_fake = np.zeros(image_size, dtype=np.uint8) annotat_files_embryo = {} annotat_files_embryo['embryo_contour'] = {} annotat_files_embryo['embryo_contour']['roi'] = roi_dict annotat_files_embryo['embryo_contour']['image'] = image_fake
nTotFiles) + ") " + ch1_filenames[nFile] print(sWork) # ADD WAITBAR # read tiff file filenameG = filebase + ".tif" I_G = plt.imread(filenameG) szG = I_G.shape imwidth = I_G.shape[1] imheight = I_G.shape[0] #read Kymo_ROI sROI = read_roi_file(filebase + ".roi") if sROI[ch1_filenames[nFile]]["type"] == "line": xcoord = list() ycoord = list() xcoord = int(sROI[ch1_filenames[nFile]]['x1']), (int( sROI[ch1_filenames[nFile]]['x2'])) ycoord = int(sROI[ch1_filenames[nFile]]['y1']), (int( sROI[ch1_filenames[nFile]]['y2'])) sROI[ch1_filenames[nFile]]["x"] = xcoord sROI[ch1_filenames[nFile]]["y"] = ycoord del sROI[ch1_filenames[nFile]]['x1'] del sROI[ch1_filenames[nFile]]['x2'] del sROI[ch1_filenames[nFile]]['y1'] del sROI[ch1_filenames[nFile]]['y2'] nPoints = len(sROI[ch1_filenames[nFile]]['x'])
def get_line_profile(image, start=(), end=(), froi='', ShowPlot=True, PlotTitle='Profile', linewidth=1, order=1, mode='constant', cval=0.0): """ This function returns the intensity profile of an image measured along a line defined by the points: start = (x_start, y_start) [i.e. (col_start row_start)] end = (x_end, y_en) [i.e. (col_end row_end)] or an ImageJ .roi file containing the line selection. A plot representing the intensity profile can be shown. Parameters ---------- image : ndarray The image grayscale (2D array) or a stack of images (3d array) with shape (slices, rows, columns). Ffor a 3D array the first axis represents the image index. start : 2-tuple of numeric scalar (float or int) (x y) [i.e. (col row)] The start point of the scan line. end : 2-tuple of numeric scalar (float or int) (x y) [i.e. (col row)] The end point of the scan line. The destination point is *included* in the profile, in constrast to standard numpy indexing. froi : string Path of the imagej file containing the line selection. ShowPlot : bool If True a canvas is created representing the Plot Profile. linewidth : int, optional Width of the scan, perpendicular to the line order : int in {0, 1, 2, 3, 4, 5}, optional The order of the spline interpolation to compute image values at non-integer coordinates. 0 means nearest-neighbor interpolation. mode : {'constant', 'nearest', 'reflect', 'mirror', 'wrap'}, optional How to compute any values falling outside of the image. cval : float, optional If `mode` is 'constant', what constant value to use outside the image. Returns ------- return_value : array The intensity profile along the scan line. The length of the profile is the ceil of the computed length of the scan line. """ if (froi and (start or end)): raise ValueError( 'Please indicate an ImageJ .roi file or two tuples of coordinates.' ) if (froi): # read roi file roi = read_roi_file(froi) # convert keys to list l = list(roi.keys()) # extract type tp = roi[l[0]]['type'] if (tp == 'line'): start = np.floor([roi[l[0]]['x1'], roi[l[0]]['y1']]) end = np.floor([roi[l[0]]['x2'], roi[l[0]]['y2']]) else: raise ValueError( "File specified does not contain a line selection.") start = start[::-1] end = end[::-1] if (image.ndim == 3): image = image.swapaxes(0, 2).swapaxes(0, 1) y = profile_line(image, start, end, linewidth, order, mode, cval) if (ShowPlot): plt.figure(PlotTitle) plt.plot(y, '-') plt.show(block=False) if (image.ndim == 3): y = y.swapaxes(0, 1) return y
def calc_nuclear_enrichment(FQ_file, binsHist, channels={'nuclei': ''}, show_plots=False, Zrange=None, dZ=2, plot_callback=None, progress_callback=None, log_callback=None): """ Enrichment at the nuclear MEMBRANE Function uses annotations generated in FIJI and creates mask based on the specified parameters. """ # Get input args. Has to be FIRST call! input_args = locals() # Get folder drive, path_and_file = os.path.splitdrive(FQ_file) path_results, file_results = os.path.split(path_and_file) file_base, ext = os.path.splitext(file_results) path_save = os.path.join( drive, path_results, file_base, 'NucEnvelopDist_{}'.format( time.strftime("%y%m%d-%H%M", time.localtime()))) if not os.path.isdir(path_save): os.makedirs(path_save) # ************************************************************************* # Load nuclear outline utils.log_message(f'Reading segmentation masks of nuclei', callback_fun=log_callback) # Generate binary masks for a selected data-set binaryGen = maskGenerator.BinaryMaskGenerator( erose_size=5, obj_size_rem=500, save_indiv=True, progress_callback=progress_callback) # Import annotations for nuclei path_annot = os.path.join(drive, path_results, 'zstack_segmentation') folderImporter = annotationImporter.FolderImporter( channels=channels, data_category={'roi': ''}, annot_ext='__RoiSet.zip', progress_callback=progress_callback) annotDict = folderImporter.load(path_annot) # The generate function uses as an input the sub-dictionary for one data-category and one channel annotatFiles = annotDict['roi']['nuclei'] mask_dict_nuclei = binaryGen.generate(annotatFiles) keys_delete = [] for k, v in annotatFiles.items(): # Make sure that key in present in mask, otherwise delete if k in mask_dict_nuclei: v.update(mask_dict_nuclei[k]) else: keys_delete.append(k) # ************************************************************************* # Load embryo outline file_embryo = os.path.join(drive, path_results, 'embryo_contour.roi') # Convert dictionary & get size of ROIS roi_import = read_roi_file(file_embryo) roi_dict = {} roi_dict['embryo'] = {} roi_dict['embryo']['type'] = roi_import['embryo_contour']['type'] roi_dict['embryo']['pos'] = np.column_stack( (roi_import['embryo_contour']['y'], roi_import['embryo_contour']['x'])) # Assemble structure to call mask generator image_size = annotatFiles.values().__iter__().__next__()['image'].shape image_fake = np.zeros(image_size, dtype=np.uint8) annotat_files_embryo = {} annotat_files_embryo['embryo_contour'] = {} annotat_files_embryo['embryo_contour']['roi'] = roi_dict annotat_files_embryo['embryo_contour']['image'] = image_fake mask_dict_embryo = binaryGen.generate(annotat_files_embryo) mask_embryo = mask_dict_embryo['embryo_contour']['mask_fill'] # ************************************************************************* # Load and analyze FQ results fq_dict = FQtoolbox.read_FQ_matlab(FQ_file) spots_all = FQtoolbox.get_rna(fq_dict) # Z position in pixel Zrna = np.divide(spots_all[:, [2]], fq_dict['settings']['microscope']['pix_z']).astype(int) # Other parameters for calculation dist_membr_RNA = np.array([]) dist_membr_pix = np.array([]) idx = 0 # Loop over all z-slices utils.log_message(f'Loop over z-slices', callback_fun=log_callback) N_annot = len(annotatFiles) for idx_file, (k_annot, v_annot) in enumerate(annotatFiles.items()): # Indicate progress via callback if progress_callback: perc = int(100 * (idx_file + 1) / (N_annot)) progress_callback({ "task": "analyze_slices", "text": f"{perc}%, {k_annot}", "progress": perc }) else: print(f'Slice: {k_annot}') # Get Z coordinate m = re.search('.*_Z([0-9]*)\.tif', k_annot) Zmask = int(m.group(1)) # Check if outside of specified z range if Zrange is not None: if not (Zrange[0] == 0 and Zrange[1] == 0): if (Zmask < Zrange[0]) or (Zmask > Zrange[1]): print(f'Z-slice outside of specified range: {Zmask}') continue # Get z-range for loop if dZ == 0: Zloop = np.logical_and(Zrna <= Zmask + dZ, Zrna >= Zmask - dZ).flatten() else: Zloop = (Zrna == Zmask).flatten() spots_loop = spots_all[Zloop, :] spots_loop_XY = np.divide( spots_loop[:, [0, 1]], fq_dict['settings']['microscope']['pix_xy']).astype(int) # Distance transform dist_nuc_outside = ndimage.distance_transform_edt( ~v_annot['mask_fill']) dist_nuc_inside = ndimage.distance_transform_edt( v_annot['mask_fill']) # Negate mask dist_nuc = dist_nuc_outside - dist_nuc_inside # Indices have to be inverted to access array dist_nuc_RNA_loop = dist_nuc[spots_loop_XY[:, 0], spots_loop_XY[:, 1]] # Get distance from membrane for all pixel in the cell dist_membr_pix_loop = dist_nuc[mask_embryo.astype(bool)] # Save values if idx == 0: dist_membr_RNA = np.copy(dist_nuc_RNA_loop) dist_membr_pix = np.copy(dist_membr_pix_loop) else: dist_membr_RNA = np.append(dist_membr_RNA, dist_nuc_RNA_loop, axis=0) dist_membr_pix = np.append(dist_membr_pix, dist_membr_pix_loop, axis=0) idx += 1 # ************************************************************************* # Load and analyze FQ results utils.log_message(f'Analyzing smFISH data', callback_fun=log_callback) x_ticks = binsHist[:-1] width = 0.9 * np.diff(binsHist) width_full = np.diff(binsHist) center = (binsHist[:-1] + binsHist[1:]) / 2 #histRNA_all, bins = np.histogram(dist_membr_RNA,binsHist ,density=False) #histPIX_all, bins = np.histogram(dist_membr_pix,binsHist ,density=False) #histRNA_norm = np.divide(histRNA_all,histPIX_all) #counts_total = np.nansum(np.multiply(histRNA_norm,width_full)) #histRNA_norm = np.divide(histRNA_norm,counts_total) # Distance of all pixel from distance map hist_pix_all, bins = np.histogram(dist_membr_pix, binsHist, density=False) hist_pix_all_norm = hist_pix_all / hist_pix_all.sum() # Distance of all RNAs hist_rna_all, bins = np.histogram(dist_membr_RNA, binsHist, density=False) hist_rna_all_norm = hist_rna_all / hist_rna_all.sum() # Re-normalize RNA distances hist_rna_all_norm_pix = np.divide(hist_rna_all_norm, hist_pix_all_norm) hist_rna_all_norm_pix = np.nan_to_num(hist_rna_all_norm_pix) # Save file with histogram histo_dist = { 'center': center, 'width': width_full, 'bins': binsHist, 'x_ticks': x_ticks, 'hist_pix_all': hist_pix_all, 'hist_pix_all_norm': hist_pix_all_norm, 'hist_rna_all': hist_rna_all, 'hist_rna_all_norm': hist_rna_all_norm, 'hist_rna_all_norm_pix': hist_rna_all_norm_pix } # Save entire analysis results as json input_args.pop('show_plot', None) input_args.pop('plot_callback', None) input_args.pop('progress_callback', None) input_args.pop('log_callback', None) analysis_results = { 'args': input_args, 'histogram': histo_dist, } name_json = os.path.join(path_save, 'DataAnalysis.json') with open(name_json, 'w') as fp: json.dump(analysis_results, fp, sort_keys=True, indent=4, cls=utils.NumpyEncoder) # Save histogram of pooled data as csv name_csv = os.path.join(path_save, '_HistogramDistances.csv') histo_dist.pop('bins', None) csv_header = ';'.join(histo_dist.keys()) hist_values = np.array(list(histo_dist.values())).transpose() np.savetxt(name_csv, hist_values, delimiter=";", fmt='%f', header=csv_header, comments='') # ************************************************************************* # Plot results # Don't show plots when they are saved if not show_plots: plt.ioff() fig1, ax = plt.subplots(3, 1) ax[0].bar(center, hist_rna_all, align='center', width=width) ax[0].set_xlabel('Dist to nuc') ax[0].set_ylabel('# RNAs') ax[0].set_xticks(x_ticks) ax[0].set_xticklabels(x_ticks.astype(int)) ax[1].bar(center, hist_pix_all, align='center', width=width) ax[1].set_xlabel('Dist to nuc') ax[1].set_ylabel('# pixels') ax[1].set_xticks(x_ticks) ax[1].set_xticklabels(x_ticks.astype(int)) ax[2].bar(center, hist_rna_all_norm_pix, align='center', width=width) ax[2].set_xlabel('Distance to nuc') ax[2].set_ylabel('RNA counts [a.u.]') ax[2].set_xticks(x_ticks) ax[2].set_xticklabels(x_ticks.astype(int)) ax[0].title.set_text('RNAs') ax[1].title.set_text('All pixel in images') ax[2].title.set_text('RNAs renormalized with pixels') plt.tight_layout() # Save and close if display not required name_save = os.path.join(path_save, '_DistanceEnrichmentSummary.png') plt.savefig(name_save, dpi=300) if not show_plots: plt.close() if plot_callback: plot_callback(name_save) if progress_callback: with open(name_save, 'rb') as f: data = f.read() result = base64.b64encode(data).decode('ascii') img_url = 'data:image/png;base64,' + result progress_callback({"task": "show_results", "src": img_url})
def test_roi_data(name, true_data): fname = load_data(name) data = read_roi.read_roi_file(fname) TestCase().assertDictEqual(data, true_data)
def main(): root_path = '/media/julien/Not_today/hne_not_today/data/crcns_data/chen_2013/' # identifier = "20120416_cell1_001" identifier = "20120416_cell1_002" # identifier = "20120417_cell3_001" # identifier = "20120417_cell3_003" # identifier = "20120515_cell1_003" # identifier = "20120417_cell4_001" # identifier = "20120627_cell3_001" # identifier = "20120515_cell1_004" # identifier = "20120417_cell4_002" # identifier = "20120417_cell3_002" # identifier = "20120627_cell3_002" # identifier = "20120417_cell1_002" # identifier = "20120417_cell4_003" # identifier = "20120417_cell5_002" # identifier = "20120515_cell1_003" # identifier = "20120515_cell1_005" # identifier = "20120515_cell1_006" # identifier = "20120627_cell4_002" # identifier = "20120627_cell4_004" # identifier = "20120627_cell4_005" # 20120417_cell4_001 two_files_version = False # data_path = os.path.join(root_path, "for_test", identifier) data_path = os.path.join(root_path, identifier) downsampling_factor = 6 # test = hdf5storage.loadmat(os.path.join(data_path, 'cell1_002.mat')) # print(f"test {test}") if two_files_version: frame_times_file = os.path.join(data_path, f"{identifier}_frame_times.mat") spike_times_file = os.path.join(data_path, f"{identifier}_spike_times.mat") frame_times = hdf5storage.loadmat(frame_times_file)['t_frame'] spike_times = hdf5storage.loadmat(spike_times_file)['spike_time'] else: info = hdf5storage.loadmat( os.path.join(data_path, f'info_{identifier}.mat')) frame_times = info['t_frame'] spike_times = info['spike_time'] frame_times = np.ndarray.flatten(frame_times) print(f"n frames {len(frame_times)}") zip_file = os.path.join(data_path, f"{identifier}_25_25.zip") roi_file = os.path.join(data_path, f"{identifier}_25_25.roi") zip_data = None if os.path.isfile(zip_file): zip_data = read_roi_zip(zip_file) else: roi = read_roi_file(roi_file) # test = hdf5storage.loadmat(os.path.join(data_path, 'p12_17_11_10_a000_CellDetect.mat')) # print(f"test {test}") # print(f"n frames {spike_times}") # print(f"n spikes {len(spike_times)}") # print(f"frames {frame_times.shape}") # print(f"spikes {spike_times}") # print(f"roi {roi}") # all_contours = [] if zip_data is not None: coords_caiman_style = np.empty((len(zip_data), ), dtype=np.object) # for i in range(len(self.map_coords)): # coords_caiman_style[i] = self.map_coords[i] for roi_index, roi in enumerate(zip_data.values()): n_points = len(roi['x']) contours = np.zeros((2, n_points), dtype="int16") contours[0] = roi['x'] contours[1] = roi['y'] coords_caiman_style[roi_index] = contours # all_contours.append(contours) # print(f"all_contours {all_contours}") else: coords_caiman_style = np.empty((1, ), dtype=np.object) roi = roi[list(roi.keys())[0]] n_points = len(roi['x']) contours = np.zeros((2, n_points), dtype="int16") contours[0] = roi['x'] contours[1] = roi['y'] coords_caiman_style[0] = contours n_times = len(frame_times) if downsampling_factor > 1: if n_times % downsampling_factor != 0: raise Exception( f"Number of frames {n_times} not divisible by {downsampling_factor}" ) n_times = n_times // downsampling_factor spikes_num = np.zeros((len(coords_caiman_style), n_times), dtype="int8") for index_spike, spike_time in enumerate(spike_times): frame = find_nearest(array=frame_times, value=spike_time) frame = int(frame / downsampling_factor) if frame == n_times: frame -= 1 spikes_num[0, frame] = 1 np.save(os.path.join(data_path, f"{identifier}_contours.npy"), coords_caiman_style) # sio.savemat(os.path.join(data_path, f"{identifier}_contours.mat"), {"AllContours": coords_caiman_style}) if downsampling_factor > 1: np.save( os.path.join( data_path, f"{identifier}_spikes_{int(60/downsampling_factor)}_hz.npy"), spikes_num) else: np.save(os.path.join(data_path, f"{identifier}_spikes.npy"), spikes_num)
diname = sorted(glob.glob(dipath)) # roi to mask for fl in range(len(rfolname)): rpath = "../data/roi/" + rfolname[fl] + "/*" rfname = glob.glob(rpath) roiname = os.listdir("../data/roi/" + rfolname[fl]) locset = [] for rf in range(len(rfname)): rname, ext = os.path.splitext(roiname[rf]) rfile = rfname[rf] roi = read_roi_file(rfile) x = roi[rname]['x'] y = roi[rname]['y'] pn = len(x) loc = np.ndarray((pn, 2), dtype=np.int32) for lo in range(len(x)): loc[lo] = (x[lo], y[lo]) locset.append(loc) for fw in range(len(locset)):
def read_roi(path): return read_roi_file(path)
def read_mri_data(root_path, if_normalized=True): '''read five types of images from the parent folder, if_normalized points to the T1 SAG images''' ims_T1s = [] ims_T1 = [] ims_T2s = [] ims_T2 = [] ims_T2st = [] pos = [] axis_ens_T1 = [] axis_ens_T2 = [] axis_ens_T2star = [] for root, dirnames, filenames in os.walk(root_path): for filename in filenames: if root.find('T1_TSE_SAG') is not -1: f = os.path.join(root, filename) nb_chosen = int(len(filenames) / 2) + 1 if f.endswith(str(nb_chosen) + '.dcm'): ds = pydicom.dcmread(f) # dcm format im_T1s = ds.pixel_array # array 这里train data是(512,512) dtype = int16 if if_normalized: im_T1s = (im_T1s - im_T1s.mean()) / im_T1s.std() ims_T1s.append(im_T1s) pos.append(os.path.abspath(os.path.dirname(root))) break if root.find('T1_Images') is not -1: f = os.path.join(root, filename) nb_chosen = int(len(filenames) / 2) if f.endswith(str(nb_chosen) + '.dcm'): ds = pydicom.dcmread(f) # dcm format im_T1 = ds.pixel_array # array 这里train data是(512,512) dtype = int16 if if_normalized: im_T1 = (im_T1 - im_T1.mean()) / im_T1.std() ims_T1.append(im_T1) break if f.endswith('.roi'): ds = read_roi_file(f) for i, key in enumerate(ds.keys()): xs = ds[key]['x'] ys = ds[key]['y'] break axis_T1 = np.array([xs, ys]).T axis_ens_T1.append(axis_T1) if root.find('T2_TSE_SAG') is not -1: f = os.path.join(root, filename) nb_chosen = int(len(filenames) / 2) + 1 if f.endswith(str(nb_chosen) + '.dcm'): ds = pydicom.dcmread(f) # dcm format im_T2s = ds.pixel_array # array 这里train data是(512,512) dtype = int16 if if_normalized: im_T2s = (im_T2s - im_T2s.mean()) / im_T2s.std() ims_T2s.append(im_T2s) break if root.find('T2_Images') is not -1: f = os.path.join(root, filename) nb_chosen = int(len(filenames) / 2) + 1 if f.endswith(str(nb_chosen) + '.dcm'): ds = pydicom.dcmread(f) # dcm format im_T2 = ds.pixel_array # array 这里train data是(512,512) dtype = int16 if if_normalized: im_T2 = (im_T2 - im_T2.mean()) / im_T2.std() ims_T2.append(im_T2) break if f.endswith('.roi'): ds = read_roi_file(f) for i, key in enumerate(ds.keys()): xs = ds[key]['x'] ys = ds[key]['y'] break axis_T2 = np.array([xs, ys]).T axis_ens_T2.append(axis_T2) if root.find('T2Star_Images') is not -1: f = os.path.join(root, filename) nb_chosen = int(len(filenames) / 2) + 1 if f.endswith(str(nb_chosen) + '.dcm'): ds = pydicom.dcmread(f) # dcm format im_T2st = ds.pixel_array # array 这里train data是(512,512) dtype = int16 if if_normalized: im_T2st = (im_T2st - im_T2st.mean()) / im_T2st.std() ims_T2st.append(im_T2st) break if f.endswith('.roi'): ds = read_roi_file(f) for i, key in enumerate(ds.keys()): xs = ds[key]['x'] ys = ds[key]['y'] break axis_T2star = np.array([xs, ys]).T axis_ens_T2star.append(axis_T2star) return np.array(ims_T1s), np.array(ims_T1), np.array(ims_T2s), np.array( ims_T2), np.array(ims_T2st), pos, np.array(axis_ens_T1), np.array( axis_ens_T2), np.array(axis_ens_T2star)
def _parse_roi_file_py3(roi_source): """Parses an individual ImageJ ROI This implementation utilises the read_roi package, which is more robust but only supports Python 3+ and not Python 2.7. Parameters ---------- roi_source : str or file object Path to file, or file object containing a single ImageJ ROI Returns ------- dict Returns a parsed ROI object, a dictionary with either a `'polygons'` or a `'mask'` field. Raises ------ IOError If there is an error reading the roi file object. ValueError If unable to parse ROI. """ # Use read_roi package to load up the roi as a dictionary roi = read_roi.read_roi_file(roi_source) # This is a dictionary with a single entry, whose key is the label # of the roi. We need to get out its contents, which is another dictionary. keys = list(roi.keys()) if len(keys) == 1: roi = roi[keys[0]] # Convert the roi dictionary into either polygon or a mask if 'x' in roi and 'y' in roi and 'n' in roi: # ROI types "freehand", "freeline", "multipoint", "point", "polygon", # "polyline", and "trace" are loaded and returned as a set of polygon # co-ordinates. coords = np.empty((roi['n'], 3), dtype=np.float) coords[:, 0] = roi['x'] coords[:, 1] = roi['y'] coords[:, 2] = roi.get('z', 0) if np.all(coords[:, 0] < 0) or np.all(coords[:, 1] < 0): raise ValueError("ROI is entirely offscreen.") return {'polygons': coords} if 'width' in roi and 'height' in roi and 'left' in roi and 'top' in roi: width = roi['width'] height = roi['height'] left = roi['left'] top = roi['top'] right = left + width bottom = top + height if right < 0 or bottom < 0: raise ValueError("ROI is entirely offscreen.") z = roi.get('z', 0) if roi['type'] == 'rectangle': # Rectangle is converted into polygon co-ordinates coords = [[left, top, z], [right, top, z], [right, bottom, z], [left, bottom, z]] coords = np.array(coords).astype('float') return {'polygons': coords} elif roi['type'] == 'oval': # Oval mask = np.zeros((z + 1, right, bottom), dtype=bool) # We subtract 0.5 because ImageJ's co-ordinate system has indices at # the pixel boundaries, and we are using indices at the pixel centers. x_mid = left + width / 2. - 0.5 y_mid = top + height / 2. - 0.5 # Ensure we only make a mask of things which are inside the image left = max(0, left) top = max(0, top) # Work out whether each pixel is inside the oval. We only need to check # pixels within the extent of the oval. xx = np.arange(left, right) yy = np.arange(top, bottom) xx = ((xx - x_mid) / (width / 2.)) ** 2 yy = ((yy - y_mid) / (height / 2.)) ** 2 dd = np.expand_dims(xx, 1) + np.expand_dims(yy, 0) mask[z, left:, top:] = dd <= 1 return {'mask': mask} elif roi['type'] == 'ellipse' or ( roi['type'] == 'freehand' and 'aspect_ratio' in roi and 'ex1' in roi ): # Ellipse # Co-ordinates of points at either end of major axis x1 = roi['ex1'] y1 = roi['ey1'] x2 = roi['ex2'] y2 = roi['ey2'] if (x1 < 0 and x2 < 0) or (y1 < 0 and y2 < 0): raise ValueError("ROI is entirely offscreen.") # Radius of major and minor axes r_radius = np.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) / 2. c_radius = r_radius * roi['aspect_ratio'] # Centre coordinates # We subtract 0.5 because ImageJ's co-ordinate system has indices at # the pixel boundaries, and we are using indices at the pixel centers. x_mid = (x1 + x2) / 2. - 0.5 y_mid = (y1 + y2) / 2. - 0.5 orientation = np.arctan2(y2 - y1, x2 - x1) # We need to make a mask which is a bit bigger than this, because # we don't know how big the ellipse will end up being. In the most # extreme case, it is a circle aligned along a cartesian axis. right = 1 + int(np.ceil(max(x1, x2) + r_radius)) bottom = 1 + int(np.ceil(max(y1, y2) + r_radius)) mask = np.zeros((z + 1, right, bottom), dtype=bool) # Generate the ellipse xx, yy = ellipse( x_mid, y_mid, r_radius, c_radius, mask.shape[1:], rotation=orientation, ) if len(xx) == 0 or len(yy) == 0: raise ValueError("Ellipse ROI is empty.") # Trim mask down to only the points needed mask = mask[:, :max(xx) + 1, :max(yy) + 1] # Convert sparse ellipse representation to mask mask[z, xx, yy] = True return {'mask': mask} else: raise ValueError( 'ROI type {} not supported'.format(roi['type']) )
def run_voronoi(parameters, verbose=True, use_roi=False, pixel_size=16.0): # parameters density_factor = parameters['density_factor'] min_samples = parameters['min_samples'] input_dir = parameters['input_dir'] output_dir = parameters['output_dir'] for filename in os.listdir(input_dir): if filename.endswith('csv'): print("voronoi clustering for file {0}".format(filename)) filepath = os.path.join(input_dir, filename) basename = os.path.splitext(filename)[0] output_path = os.path.join(output_dir, basename+'_voronoi.xlsx') locs = pd.read_csv(filepath) if use_roi: roi_zip_path = os.path.join(input_dir, basename + '_roiset.zip') roi_file_path = os.path.join(input_dir, basename + '_roiset.roi') if os.path.exists(roi_zip_path): rois = read_roi_zip(roi_zip_path) elif os.path.exists(roi_file_path): rois = read_roi_file(roi_file_path) else: raise ValueError(("No ImageJ roi file exists -" "you should put the file in the same" "directory as the data")) coords = {} for roi_id, roi in rois.items(): for k, v in roi.items(): if not isinstance(v, str): roi[k] = float(v) * pixel_size coords[roi_id] = (locs[ (locs['x [nm]'] > roi['left']) & (locs['x [nm]'] < roi['left'] + roi['width']) & (locs['y [nm]'] > roi['top']) & (locs['y [nm]'] < roi['top'] + roi['height'])] ).reset_index(drop=True) else: coords = dict([('image', locs)]) for roi_id in coords.keys(): df = coords[roi_id] if len(df.index) == 0: print("no coords in roi") continue voronoi_df = voronoi(df, density_factor, min_samples, show_plot=verbose, verbose=verbose) cluster_locs_df = voronoi_df[voronoi_df['lk'] != -1] labels = cluster_locs_df['lk'].unique() cluster_stats = {} cluster_stats['area'] = [] cluster_stats['occupancy'] = [] for m in labels: cluster = cluster_locs_df[cluster_locs_df.lk == m] cluster_stats['area'].append(cluster['area'].sum()) cluster_stats['occupancy'].append(len(cluster.index)) cluster_stats_df = pd.DataFrame(cluster_stats) if any(labels): writer = pd.ExcelWriter(output_path, engine='openpyxl') if os.path.exists(output_path): book = load_workbook(output_path) writer.book = book writer.sheets = dict( (ws.title, ws) for ws in book.worksheets ) cluster_locs_df.to_excel( writer, sheet_name='{0} localisations'.format(roi_id), index=False ) cluster_stats_df.to_excel( writer, sheet_name='{0} voronoi stats'.format(roi_id), index=False ) writer.save() else: print("No clusters found in {0}".format(filename)) continue
cur_sequence = roi_filename_split2[len(roi_filename_split2) - 2] if (cur_patient == patient) and (cur_sequence == find_sequence): flag = 1 break # ADC, DWI both exist if flag == 1: continue print(patient, fid, sequence, find_sequence, slice) # read roi file roi_object = read_roi_file(os.path.join(ROIPath, roi_file)) roi_temp = roi_object[roi_filename] # find image dimension and path CSV_images_object.seek(0) CSV_images_reader = csv.DictReader(CSV_images_object) for row in CSV_images_reader: if row['ProxID'].split('-')[1] == patient: if ((len(roi_filename_split) == 4) and (row['fid'] == str(fid))) or (len(roi_filename_split) == 3): if row['DCMSerDescr'] == find_sequence or \ ((find_sequence == ImageSequence_ROI[3]) and (row['DCMSerDescr'] == ImageSequence[3])): image_dimension = row['Dim'].split('x') image_path = row['DCMSerUID']
def run_optics(parameters, verbose=True, use_roi=False, pixel_size=16.0): # parameters eps = parameters['eps'] eps_extract = parameters['eps_extract'] min_samples = parameters['min_samples'] input_dir = parameters['input_dir'] output_dir = parameters['output_dir'] data_source = parameters['data_source'] for filename in os.listdir(input_dir): if 'nstorm' in data_source: ext = 'txt' elif 'thunderstorm' in data_source: ext = 'csv' file_ext = os.path.splitext(filename)[1] if ext in file_ext: print("optics clustering for file {0}".format(filename)) filepath = os.path.join(input_dir, filename) basename = os.path.splitext(filename)[0] output_path = os.path.join(output_dir, basename+'_optics.xlsx') data = Localisations(filepath, source=data_source) points = data.points xy = points.as_matrix(columns=['x', 'y']) if use_roi: roi_zip_path = os.path.join(input_dir, basename + '_roiset.zip') roi_file_path = os.path.join(input_dir, basename + '_roiset.roi') if os.path.exists(roi_zip_path): rois = read_roi_zip(roi_zip_path) elif os.path.exists(roi_file_path): rois = read_roi_file(roi_file_path) else: raise ValueError(("No ImageJ roi file exists -" "you should put the file in the same" "directory as the data")) coords = {} for roi_id, roi in rois.items(): for k, v in roi.items(): if not isinstance(v, str): roi[k] = float(v) * pixel_size coords[roi_id] = xy[(xy[:, 0] > roi['left']) & (xy[:, 0] < roi['left'] + roi['width']) & (xy[:, 1] > roi['top']) & (xy[:, 1] < roi['top'] + roi['height'])] else: coords = dict([('image', xy)]) (optics_clusters, noise) = ( optics_clustering(coords, eps=eps, eps_extract=eps_extract, min_samples=min_samples) ) if verbose: if optics_clusters: for roi_id in optics_clusters.keys(): plot_filename = os.path.join( output_dir, basename + '_{0}_clusters.png'.format(roi_id) ) if noise: noise_in_roi = noise[roi_id] else: noise_in_roi = None plot_optics_clusters(optics_clusters[roi_id], noise=noise_in_roi, save=True, filename=plot_filename) for roi in optics_clusters.keys(): oc = optics_clusters[roi] if oc.n_clusters > 0: oc.save(output_path, sheetname=roi) else: print("No clusters found in {0}".format(filename)) continue