filtered_imgs = deepcopy(imgs) for selector in imgs._iter_axes(): data = filtered_imgs.get_slice(selector)[0] scaled = data / scale_factors[selector[Axes.ROUND.value], selector[Axes.CH.value]] filtered_imgs.set_slice(selector, scaled, [Axes.ZPLANE]) # Decode with PixelSpotDecoder psd = DetectPixels.PixelSpotDecoder( codebook=experiment.codebook, metric= 'euclidean', # distance metric to use for computing distance between a pixel vector and a codeword norm_order= 2, # the L_n norm is taken of each pixel vector and codeword before computing the distance. this is n distance_threshold= 0.5176, # minimum distance between a pixel vector and a codeword for it to be called as a gene magnitude_threshold= 1.77e-5, # discard any pixel vectors below this magnitude min_area= 2, # do not call a 'spot' if it's area is below this threshold (measured in pixels) max_area=np. inf, # do not call a 'spot' if it's area is above this threshold (measured in pixels) ) initial_spot_intensities, prop_results = psd.run(filtered_imgs) # filter spots that do not pass thresholds spot_intensities = initial_spot_intensities.loc[initial_spot_intensities[ Features.PASSES_THRESHOLDS]] # Example of how to access the spot attributes print(
from starfish.spots import DetectPixels from starfish.types import Features # how much magnitude should a barcode have for it to be considered by decoding? this was set by looking at # the plot above magnitude_threshold = 0.5 # how big do we expect our spots to me, min/max size. this was set to be equivalent to the parameters # determined by the Zhang lab. area_threshold = (5, 30) # how close, in euclidean space, should the pixel barcode be to the nearest barcode it was called to? # here, I set this to be a large number, so I can inspect the distribution of decoded distances below distance_threshold = 3 psd = DetectPixels.PixelSpotDecoder(codebook=experiment.codebook, metric='euclidean', distance_threshold=distance_threshold, magnitude_threshold=magnitude_threshold, min_area=area_threshold[0], max_area=area_threshold[1]) initial_spot_intensities, results = psd.run(filtered_imgs) spots_df = initial_spot_intensities.to_features_dataframe() spots_df['area'] = np.pi * spots_df['radius']**2 spots_df = spots_df.loc[spots_df[Features.PASSES_THRESHOLDS]] spots_df.head() ################################################################################################### # Compare to benchmark results # ---------------------------- # The below plot aggregates gene copy number across cells in the field of view and compares the # results to the same copy numbers from the authors' pipeline. This can likely be improved by
sbp = Filter.Clip(p_max=99.8, level_method=Levels.SCALE_BY_CHUNK) scaled = sbp.run(background_corrected, n_processes=1, in_place=False) f = plot_scaling_result(background_corrected, scaled) ################################################################################################### # Detect Spots # ------------ # We use a pixel spot decoder to identify the gene target for each spot. from starfish.spots import DetectPixels psd = DetectPixels.PixelSpotDecoder(codebook=exp.codebook, metric='euclidean', distance_threshold=0.5, magnitude_threshold=0.1, min_area=7, max_area=50) pixel_decoded, ccdr = psd.run(scaled) ################################################################################################### # plot a mask that shows where pixels have decoded to genes. f, ax = plt.subplots() ax.imshow(np.squeeze(ccdr.decoded_image), cmap=plt.cm.nipy_spectral) ax.axis("off") ax.set_title("Pixel Decoding Results") ################################################################################################### # Get the total counts for each gene from each spot detector. Do the below values make sense for # this tissue and this probeset?
scale_factors = { (t[Axes.ROUND], t[Axes.CH]): t['scale_factor'] for t in experiment.extras['scale_factors'] } filtered_imgs = deepcopy(imgs) for selector in imgs._iter_axes(): data = filtered_imgs.get_slice(selector)[0] scaled = data / scale_factors[selector[Axes.ROUND.value], selector[Axes.CH.value]] filtered_imgs.set_slice(selector, scaled, [Axes.ZPLANE]) # Decode with PixelSpotDecoder psd = DetectPixels.PixelSpotDecoder( codebook=experiment.codebook, metric='euclidean', norm_order=2, distance_threshold=0.5176, magnitude_threshold=1.77e-5, min_area=2, max_area=np.inf, ) initial_spot_intensities, prop_results = psd.run(filtered_imgs) # Select only decoded spots that pass thresholds and map to genes in codebook decoded = initial_spot_intensities.loc[initial_spot_intensities[Features.PASSES_THRESHOLDS]] decoded_filtered = decoded[decoded.target != 'nan'] # Load cell mask roi_path = os.path.join(os.path.dirname("__file__"), 'RoiSet.zip') masks = BinaryMaskCollection.from_fiji_roi_set(path_to_roi_set_zip=roi_path, original_image=dapi) # Assign spots to cells by labeling each spot with cell_id al = AssignTargets.Label()
def process_fov(field_num: int, experiment_str: str): """Process a single field of view of MERFISH data Parameters ---------- field_num : int the field of view to process experiment_str : int path of experiment json file Returns ------- DecodedSpots : tabular object containing the locations of detected spots. """ fov_str: str = f"fov_{int(field_num):03d}" # load experiment experiment = starfish.Experiment.from_json(experiment_str) print(f"Loading fov: {fov_str}") fov = experiment[fov_str] imgs = fov.get_image(FieldOfView.PRIMARY_IMAGES) print("Gaussian High Pass") ghp = Filter.GaussianHighPass(sigma=3) high_passed = ghp.run(imgs, verbose=True, in_place=False) print("Deconvolve") dpsf = Filter.DeconvolvePSF(num_iter=15, sigma=2, level_method=Levels.SCALE_SATURATED_BY_CHUNK) deconvolved = dpsf.run(high_passed, verbose=True, in_place=False) print("Guassian Low Pass") glp = Filter.GaussianLowPass(sigma=1) low_passed = glp.run(deconvolved, in_place=False, verbose=True) scale_factors = {(t[Axes.ROUND], t[Axes.CH]): t['scale_factor'] for t in experiment.extras['scale_factors']} filtered_imgs = deepcopy(low_passed) for selector in imgs._iter_axes(): data = filtered_imgs.get_slice(selector)[0] scaled = data / scale_factors[selector[Axes.ROUND.value], selector[Axes.CH.value]] filtered_imgs.set_slice(selector, scaled, [Axes.ZPLANE]) print("Decode") psd = DetectPixels.PixelSpotDecoder( codebook=experiment.codebook, metric= 'euclidean', # distance metric to use for computing distance between a pixel vector and a codeword norm_order= 2, # the L_n norm is taken of each pixel vector and codeword before computing the distance. this is n distance_threshold= 0.5176, # minimum distance between a pixel vector and a codeword for it to be called as a gene magnitude_threshold= 1.77e-5, # discard any pixel vectors below this magnitude min_area= 2, # do not call a 'spot' if it's area is below this threshold (measured in pixels) max_area=np. inf, # do not call a 'spot' if it's area is above this threshold (measured in pixels) ) initial_spot_intensities, prop_results = psd.run(filtered_imgs) spot_intensities = initial_spot_intensities.loc[initial_spot_intensities[ Features.PASSES_THRESHOLDS]] df = spot_intensities.to_decoded_spots() return df