def build_parser(): parser = argparse.ArgumentParser() parser.add_argument("--profile", action="store_true", help="enable profiling") parser.add_argument("--noop", help=argparse.SUPPRESS, dest="starfish_command", action="store_const", const=noop) subparsers = parser.add_subparsers(dest="starfish_command") Registration._add_to_parser(subparsers) Filter._add_to_parser(subparsers) SpotFinder.add_to_parser(subparsers) Segmentation._add_to_parser(subparsers) TargetAssignment.add_to_parser(subparsers) Decoder.add_to_parser(subparsers) show_group = subparsers.add_parser("show") show_group.add_argument("in_json", type=FsExistsType()) show_group.add_argument("--sz", default=10, type=int, help="Figure size") show_group.set_defaults(starfish_command=show) build_group = subparsers.add_parser("build") BuilderCli.add_to_parser(build_group) validate_group = subparsers.add_parser("validate") ValidateCli.add_to_parser(validate_group) return parser
def preprocess(dapi): blur = Filter.GaussianLowPass(sigma=5) blurred = blur.run(dapi) clip = Filter.Clip(p_min=1, p_max=95, level_method=Levels.SCALE_BY_CHUNK) clipped = clip.run(blurred) return clipped
def test_allen_smFISH_cropped_data(): # set random seed to errors provoked by optimization functions np.random.seed(777) # load the experiment experiment = starfish.data.allen_smFISH(use_test_data=True) primary_image = experiment.fov().get_image(FieldOfView.PRIMARY_IMAGES) clip = Filter.Clip(p_min=10, p_max=100) clipped_image = clip.run(primary_image, in_place=False) bandpass = Filter.Bandpass(lshort=0.5, llong=7, threshold=None, truncate=4) bandpassed_image = bandpass.run(clipped_image, in_place=False) clip = Filter.Clip(p_min=10, p_max=100, is_volume=False) clipped_bandpassed_image = clip.run(bandpassed_image, in_place=False) sigma = (1, 0, 0) # filter only in z, do nothing in x, y glp = Filter.GaussianLowPass(sigma=sigma, is_volume=True) z_filtered_image = glp.run(clipped_bandpassed_image, in_place=False) lmpf = DetectSpots.TrackpyLocalMaxPeakFinder( spot_diameter=3, min_mass=300, max_size=3, separation=5, noise_size=0.65, preprocess=False, percentile=10, verbose=True, is_volume=True, ) intensities = lmpf.run(z_filtered_image) # noqa
def iss_pipeline(fov, codebook): primary_image = fov.get_image(starfish.FieldOfView.PRIMARY_IMAGES) # register the raw image learn_translation = LearnTransform.Translation( reference_stack=fov.get_image('dots'), axes=Axes.ROUND, upsampling=100) max_projector = Filter.Reduce((Axes.CH, Axes.ZPLANE), func="max", module=Filter.Reduce.FunctionSource.np) transforms_list = learn_translation.run(max_projector.run(primary_image)) warp = ApplyTransform.Warp() registered = warp.run(primary_image, transforms_list=transforms_list, in_place=False, verbose=True) # filter raw data masking_radius = 15 filt = Filter.WhiteTophat(masking_radius, is_volume=False) filtered = filt.run(registered, verbose=True, in_place=False) # detect spots using laplacian of gaussians approach p = DetectSpots.BlobDetector( min_sigma=1, max_sigma=10, num_sigma=30, threshold=0.01, measurement_type='mean', ) intensities = p.run(filtered, blobs_image=fov.get_image('dots'), blobs_axes=(Axes.ROUND, Axes.ZPLANE)) # decode the pixel traces using the codebook decoded = codebook.decode_per_round_max(intensities) # segment cells seg = Segment.Watershed( nuclei_threshold=.16, input_threshold=.22, min_distance=57, ) label_image = seg.run(primary_image, fov.get_image('dots')) # assign spots to cells ta = AssignTargets.Label() assigned = ta.run(label_image, decoded) return assigned, label_image
def test_save_and_load(tmp_path): """Verify that we can save the label image and load it correctly.""" array = np.zeros((2, 3, 4), dtype=np.int32) pixel_coordinates = { Axes.X: [2, 3, 4, 5], Axes.ZPLANE: [0, 1], } physical_coordinates = { Coordinates.X: [0, 0.5, 1.0, 1.5], Coordinates.Y: [0, 0.2, 0.4], Coordinates.Z: [0, 0.1], } log = Log() # instantiate a filter (even though that makes no sense in this context) filt = Filter.Reduce((Axes.ROUND,), func="max") log.update_log(filt) label_image = LabelImage.from_label_array_and_ticks( array, pixel_coordinates, physical_coordinates, log) label_image.to_netcdf(tmp_path / "label_image.netcdf") loaded_label_image = LabelImage.open_netcdf(tmp_path / "label_image.netcdf") assert label_image.xarray.equals(loaded_label_image.xarray) assert label_image.xarray.attrs == loaded_label_image.xarray.attrs
def process_fov(fov: FieldOfView, codebook: Codebook) -> DecodedIntensityTable: """Process a single field of view of ISS data Parameters ---------- fov : FieldOfView the field of view to process codebook : Codebook the Codebook to use for decoding Returns ------- DecodedSpots : tabular object containing the locations of detected spots. """ # note the structure of the 5D tensor containing the raw imaging data imgs = fov.get_image(FieldOfView.PRIMARY_IMAGES) dots = fov.get_image("dots") nuclei = fov.get_image("nuclei") print("Learning Transform") learn_translation = LearnTransform.Translation(reference_stack=dots, axes=Axes.ROUND, upsampling=1000) transforms_list = learn_translation.run( imgs.reduce({Axes.CH, Axes.ZPLANE}, func="max")) print("Applying transform") warp = ApplyTransform.Warp() registered_imgs = warp.run(imgs, transforms_list=transforms_list, verbose=True) print("Filter WhiteTophat") filt = Filter.WhiteTophat(masking_radius=15, is_volume=False) filtered_imgs = filt.run(registered_imgs, verbose=True) filt.run(dots, verbose=True, in_place=True) filt.run(nuclei, verbose=True, in_place=True) print("Detecting") detector = FindSpots.BlobDetector( min_sigma=1, max_sigma=10, num_sigma=30, threshold=0.01, measurement_type='mean', ) dots_max = dots.reduce((Axes.ROUND, Axes.ZPLANE), func="max", module=FunctionSource.np) spots = detector.run(image_stack=filtered_imgs, reference_image=dots_max) print("Decoding") decoder = DecodeSpots.PerRoundMaxChannel(codebook=codebook) decoded = decoder.run(spots=spots) return decoded
def process_fov(field_num: int, experiment_str: str): """Process a single field of view of ISS 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] # note the structure of the 5D tensor containing the raw imaging data imgs = fov.get_image(FieldOfView.PRIMARY_IMAGES) dots = fov.get_image("dots") nuclei = fov.get_image("nuclei") print("Learning Transform") learn_translation = LearnTransform.Translation(reference_stack=dots, axes=Axes.ROUND, upsampling=1000) transforms_list = learn_translation.run(imgs.reduce({Axes.CH, Axes.ZPLANE}, func="max")) print("Applying transform") warp = ApplyTransform.Warp() registered_imgs = warp.run(imgs, transforms_list=transforms_list, in_place=True, verbose=True) print("Filter WhiteTophat") filt = Filter.WhiteTophat(masking_radius=15, is_volume=False) filtered_imgs = filt.run(registered_imgs, verbose=True, in_place=True) filt.run(dots, verbose=True, in_place=True) filt.run(nuclei, verbose=True, in_place=True) print("Detecting") detector = DetectSpots.BlobDetector( min_sigma=1, max_sigma=10, num_sigma=30, threshold=0.01, measurement_type='mean', ) intensities = detector.run(filtered_imgs, blobs_image=dots, blobs_axes=(Axes.ROUND, Axes.ZPLANE)) decoded = experiment.codebook.decode_per_round_max(intensities) df = decoded.to_decoded_dataframe() return df
def test_allen_smFISH_cropped_data(): # set random seed to errors provoked by optimization functions np.random.seed(777) # load the experiment experiment = starfish.data.allen_smFISH(use_test_data=True) primary_image = experiment.fov().get_image(FieldOfView.PRIMARY_IMAGES) clip = Filter.Clip(p_min=10, p_max=100) clipped_image = clip.run(primary_image, in_place=False) bandpass = Filter.Bandpass(lshort=0.5, llong=7, threshold=0.0, truncate=4) bandpassed_image = bandpass.run(clipped_image, in_place=False) clip = Filter.Clip(p_min=10, p_max=100, is_volume=False) clipped_bandpassed_image = clip.run(bandpassed_image, in_place=False) sigma = (1, 0, 0) # filter only in z, do nothing in x, y glp = Filter.GaussianLowPass(sigma=sigma, is_volume=True) z_filtered_image = glp.run(clipped_bandpassed_image, in_place=False) tlmpf = FindSpots.TrackpyLocalMaxPeakFinder( spot_diameter=5, # must be odd integer min_mass=0.02, max_size=2, # this is max radius separation=7, noise_size=0.65, # this is not used because preprocess is False preprocess=False, percentile=10, # this is irrelevant when min_mass, spot_diameter, and max_size are set properly verbose=True, is_volume=True, ) spots = tlmpf.run(z_filtered_image) # noqa decoder = starfish.spots.DecodeSpots.PerRoundMaxChannel( codebook=experiment.codebook, trace_building_strategy=TraceBuildingStrategies.SEQUENTIAL ) decoder.run(spots=spots)
def iss_pipeline(fov, codebook): primary_image = fov.get_image(starfish.FieldOfView.PRIMARY_IMAGES) # register the raw image learn_translation = LearnTransform.Translation( reference_stack=fov.get_image('dots'), axes=Axes.ROUND, upsampling=100) transforms_list = learn_translation.run( primary_image.reduce({Axes.CH, Axes.ZPLANE}, func="max")) warp = ApplyTransform.Warp() registered = warp.run(primary_image, transforms_list=transforms_list, in_place=False, verbose=True) # filter raw data masking_radius = 15 filt = Filter.WhiteTophat(masking_radius, is_volume=False) filtered = filt.run(registered, verbose=True, in_place=False) bd = FindSpots.BlobDetector( min_sigma=1, max_sigma=10, num_sigma=30, threshold=0.01, measurement_type='mean', ) # detect spots using laplacian of gaussians approach dots_max = fov.get_image('dots').reduce((Axes.ROUND, Axes.ZPLANE), func="max", module=FunctionSource.np) # locate spots in a reference image spots = bd.run(reference_image=dots_max, image_stack=filtered) # decode the pixel traces using the codebook decoder = DecodeSpots.PerRoundMaxChannel(codebook=codebook) decoded = decoder.run(spots=spots) # segment cells seg = Segment.Watershed( nuclei_threshold=.16, input_threshold=.22, min_distance=57, ) label_image = seg.run(primary_image, fov.get_image('dots')) # assign spots to cells ta = AssignTargets.Label() assigned = ta.run(label_image, decoded) return assigned, label_image
def masksFromWatershed( img_stack: List[ImageStack], img_threshold: float, min_dist: int, min_size: int, max_size: int, masking_radius: int, ) -> List[BinaryMaskCollection]: """ Runs a primitive thresholding and watershed pipeline to generate segmentation masks. Parameters ---------- img_threshold: float Global threshold value for images. min_dist: int Minimum distance (pixels) between distance transformed peaks. min_size: int Minimum size for a cell (in pixels) max_size: int Maxiumum size for a cell (in pixels) masking_radius: int Radius for white tophat noise filter. Returns ------- list[BinaryMaskCollection]: Binary masks for each FOV. """ wt_filt = ImgFilter.WhiteTophat(masking_radius, is_volume=False) thresh_filt = Binarize.ThresholdBinarize(img_threshold) min_dist_label = Filter.MinDistanceLabel(min_dist, 1) area_filt = Filter.AreaFilter(min_area=min_size, max_area=max_size) area_mask = Filter.Reduce("logical_or", lambda shape: np.zeros(shape=shape, dtype=bool)) segmenter = Segment.WatershedSegment() masks = [] for img in img_stack: img_flat = img.reduce({Axes.ROUND}, func="max") working_img = wt_filt.run(img_flat, in_place=False) working_img = thresh_filt.run(working_img) labeled = min_dist_label.run(working_img) working_img = area_filt.run(labeled) working_img = area_mask.run(working_img) masks.append(segmenter.run(img_flat, labeled, working_img)) return masks
def iss_pipeline(fov, codebook): primary_image = fov[starfish.FieldOfView.PRIMARY_IMAGES] # register the raw images registration = Registration.FourierShiftRegistration( upsampling=1000, reference_stack=fov['dots'] ) registered = registration.run(primary_image, in_place=False) # filter raw data masking_radius = 15 filt = Filter.WhiteTophat(masking_radius, is_volume=False) filtered = filt.run(registered, verbose=True, in_place=False) # detect spots using laplacian of gaussians approach p = SpotFinder.BlobDetector( min_sigma=1, max_sigma=10, num_sigma=30, threshold=0.01, measurement_type='mean', ) mp = fov['dots'].max_proj(Indices.ROUND, Indices.Z) mp_numpy = mp._squeezed_numpy(Indices.ROUND, Indices.Z) intensities = p.run(filtered, blobs_image=mp_numpy) # decode the pixel traces using the codebook decoded = codebook.decode_per_round_max(intensities) # segment cells seg = Segmentation.Watershed( nuclei_threshold=.16, input_threshold=.22, min_distance=57, ) label_image = seg.run(primary_image, fov['nuclei']) # assign spots to cells ta = TargetAssignment.Label() assigned = ta.run(label_image, decoded) return assigned, label_image
def iss_pipeline(fov, codebook): primary_image = fov.primary_image # register the raw images registration = Registration.FourierShiftRegistration( upsampling=1000, reference_stack=fov['dots'] ) registered = registration.run(primary_image, in_place=False) # filter raw data masking_radius = 15 filt = Filter.WhiteTophat(masking_radius, is_volume=False) filtered = filt.run(registered, verbose=True, in_place=False) # detect spots using laplacian of gaussians approach p = SpotFinder.GaussianSpotDetector( min_sigma=1, max_sigma=10, num_sigma=30, threshold=0.01, measurement_type='mean', ) blobs_image = fov['dots'].max_proj(Indices.ROUND, Indices.Z) intensities = p.run(filtered, blobs_image=blobs_image) # decode the pixel traces using the codebook decoded = codebook.decode_per_round_max(intensities) # segment cells seg = Segmentation.Watershed( dapi_threshold=.16, input_threshold=.22, min_distance=57, ) regions = seg.run(primary_image, fov['nuclei']) # assign spots to cells ta = TargetAssignment.PointInPoly2D() assigned = ta.run(decoded, regions) return assigned, regions
# Register the data # ----------------- # The first step in BaristaSeq is to do some rough registration. For this data, the rough # registration has been done for us by the authors, so it is omitted from this notebook. ################################################################################################### # Project into 2D # --------------- # BaristaSeq is typically processed in 2D. Starfish allows users to reduce data using arbitrary # methods via :py:class:`.image.Filter.Reduce`. Here we max project Z for both the nissl images and # the primary images. from starfish.image import Filter from starfish.types import FunctionSource max_projector = Filter.Reduce((Axes.ZPLANE, ), func=FunctionSource.np("max")) z_projected_image = max_projector.run(img) z_projected_nissl = max_projector.run(nissl) # show the projected data f, (ax1, ax2) = plt.subplots(ncols=2) imshow_plane(z_projected_image, sel={ Axes.CH: 0, Axes.ROUND: 0 }, ax=ax1, title="primary image") imshow_plane(z_projected_nissl, sel={ Axes.CH: 0,
# EPY: START code experiment.codebook # EPY: END code # EPY: START markdown #All of our implemented operations leverage the `Stack.image.apply` method to apply a single function over each of the tiles or volumes in the FOV, depending on whether the method accepts a 2d or 3d array. Below, we're clipping each image independently at the 10th percentile. I've placed the imports next to the methods so that you can easily locate the code, should you want to look under the hood and understand what parameters have been chosen. # #The verbose flag for our apply loops could use a bit more refinement. We should be able to tell it how many images it needs to process from looking at the image stack, but for now it's dumb so just reports the number of tiles or volumes it's processed. This FOV has 102 images over 3 volumes. # #This data is quite large (2.6 GB in memory) so we're going to run in-place to avoid exploding memory usage # EPY: END markdown # EPY: START code from starfish.image import Filter clip = Filter.Clip(p_min=10, p_max=100) clip.run(primary_image, verbose=True, in_place=True) # EPY: END code # EPY: START markdown #If you ever want to visualize the image in the notebook, we've added a widget to do that. The first parameter is an indices dict that specifies which imaging round, channel, z-slice you want to view. The result is a pageable visualization across that arbitrary set of slices. Below I'm visualizing the first channel, which the codebook indicates is Nmnt. # #The plot uses `rescale` to expand the dynamic range of the data to cover `[0, 1]`. # EPY: END markdown # EPY: START code primary_image.show_stack({ Indices.CH.value: 0, Indices.Z.value: 17 }, rescale=True)
# Process dapi images by blurring and clipping def preprocess(dapi): blur = Filter.GaussianLowPass(sigma=5) blurred = blur.run(dapi) clip = Filter.Clip(p_min=1, p_max=95, level_method=Levels.SCALE_BY_CHUNK) clipped = clip.run(blurred) return clipped dapi = preprocess(dapi) # Need ilastik script and ilastik project with trained classifier to instantiate filter ilastik_exe_path = os.path.join(os.path.dirname("__file__"), 'run_ilastik.sh') ilastik_proj_path = os.path.join(os.path.dirname("__file__"), 'merfish_dapi.ilp') ipp = Filter.IlastikPretrainedProbability(ilastik_executable=ilastik_exe_path, ilastik_project=ilastik_proj_path) # Run IlastikPretrainedProbability filter to get probabilities of 'Label 1' as ImageStack # probabilities = ipp.run(stack=dapi) ################################################################################################### # Loading ilastik Probability Map # =============================== # # If you already have probability maps of your images from ilastik or prefer to use the ilastik # GUI it is possible to load the exported hdf5 files into starfish. When using the 'Prediction # Export' panel in ilastik be sure to use ``Source: Probabilities`` and ``Format: hdf5``. If you # edit the Dataset name then it must also be passed as ``dataset_name`` to # :py:meth:`.import_ilastik_probabilities`. The example below loads the same probability map that # would have been generated in the first section of this tutorial.
Indices.Z) # EPY: END code # EPY: START code experiment = starfish.data.MERFISH() merfish_nuclei_mp = experiment.fov()['nuclei'].max_proj( Indices.CH, Indices.ROUND, Indices.Z) merfish_nuclei__mp_numpy = merfish_nuclei_mp._squeezed_numpy( Indices.CH, Indices.ROUND, Indices.Z) # merfish doesn't have a dots image, and some of the channels are stronger than others. # We can use the scale factors to get the right levels merfish_background = experiment.fov()[FieldOfView.PRIMARY_IMAGES].max_proj( Indices.CH, Indices.ROUND) from starfish.image import Filter clip = Filter.Clip(p_max=99.7) merfish_dots = clip.run(merfish_background) merfish_mp = merfish_dots.max_proj(Indices.CH, Indices.ROUND, Indices.Z) merfish_mp_numpy = merfish_mp._squeezed_numpy(Indices.CH, Indices.ROUND, Indices.Z) # EPY: END code # EPY: START markdown ### Load Decoded Images # EPY: END markdown # EPY: START markdown #Numpy load can't download files from s3 either. # EPY: END markdown
from starfish.util.plot import imshow_plane # for this vignette, we'll pick one plane and track it through the processing steps plane_selector = {Axes.CH: 0, Axes.ROUND: 0, Axes.ZPLANE: 0} imshow_plane(imgs, sel=plane_selector, title='Round: 0, Chanel:0') ################################################################################################### # Filter and scale raw data before decoding into spatially resolved gene expression # --------------------------------------------------------------------------------- # First, we equalize the intensity of the images by scaling each image by its maximum intensity, # which is equivalent to scaling by the 100th percentile value of the pixel values in each image. from starfish.image import Filter from starfish.types import Levels sc_filt = Filter.Clip(p_max=100, level_method=Levels.SCALE_BY_CHUNK) norm_imgs = sc_filt.run(imgs) ################################################################################################### # Next, for each imaging round, and each pixel location, we zero the intensity values across all # three color channels if the magnitude of this 3 vector is below a threshold. As such, the code # value associated with these pixels will be the blank. This is necessary to support euclidean # decoding for codebooks that include blank values. z_filt = Filter.ZeroByChannelMagnitude(thresh=.05, normalize=False) filtered_imgs = z_filt.run(norm_imgs) ################################################################################################### # Decode the processed data into spatially resolved gene expression profiles # -------------------------------------------------------------------------- # Here, starfish decodes each pixel value, across all rounds and channels, into the corresponding
# EPY: START code experiment.codebook # EPY: END code # EPY: START markdown ### Filter and scale raw data before decoding # EPY: END markdown # EPY: START markdown #Begin filtering with a high pass filter to remove background signal. # EPY: END markdown # EPY: START code from starfish.image import Filter ghp = Filter.GaussianHighPass(sigma=3) high_passed = ghp.run(primary_image, verbose=True, in_place=False) # EPY: END code # EPY: START markdown #The below algorithm deconvolves out the point spread function introduced by the microcope and is specifically designed for this use case. The number of iterations is an important parameter that needs careful optimization. # EPY: END markdown # EPY: START code from starfish.types import Clip dpsf = Filter.DeconvolvePSF(num_iter=15, sigma=2, clip_method=Clip.SCALE_BY_CHUNK) deconvolved = dpsf.run(high_passed, verbose=True, in_place=False) # EPY: END code # EPY: START markdown #Recall that the image is pre-registered, as stated above. Despite this, individual RNA molecules may still not be perfectly aligned across imaging rounds. This is crucial in order to read out a measure of the itended barcode (across imaging rounds) in order to map it to the codebook. To solve for potential mis-alignment, the images can be blurred with a 1-pixel Gaussian kernel. The risk here is that this will obfuscate signals from nearby molecules.
def filter_white_tophat(imgs, dots, masking_radius): wth = Filter.WhiteTophat(masking_radius=masking_radius) return wth.run(imgs), wth.run(dots)
# EPY: START code experiment.codebook # EPY: END code # EPY: START markdown ### Filter and scale raw data before decoding # EPY: END markdown # EPY: START markdown #Begin filtering with a high pass filter to remove background signal. # EPY: END markdown # EPY: START code from starfish.image import Filter ghp = Filter.GaussianHighPass(sigma=3) high_passed = ghp.run(primary_image, verbose=True, in_place=False) # EPY: END code # EPY: START markdown #The below algorithm deconvolves out the point spread function introduced by the microcope and is specifically designed for this use case. The number of iterations is an important parameter that needs careful optimization. # EPY: END markdown # EPY: START code dpsf = Filter.DeconvolvePSF(num_iter=15, sigma=2, clip=True) deconvolved = dpsf.run(high_passed, verbose=True, in_place=False) # EPY: END code # EPY: START markdown #Recall that the image is pre-registered, as stated above. Despite this, individual RNA molecules may still not be perfectly aligned across imaging rounds. This is crucial in order to read out a measure of the itended barcode (across imaging rounds) in order to map it to the codebook. To solve for potential mis-alignment, the images can be blurred with a 1-pixel Gaussian kernel. The risk here is that this will obfuscate signals from nearby molecules. #
.. warning:: :py:class:`.TrackpyLocalMaxPeakFinder` is not compatible with cropped data sets. """ from starfish import data from starfish import FieldOfView from starfish.image import Filter from starfish.spots import FindSpots experiment = data.allen_smFISH(use_test_data=True) img = experiment['fov_001'].get_image(FieldOfView.PRIMARY_IMAGES) # filter to remove noise, remove background, blur, and clip bandpass = Filter.Bandpass(lshort=.5, llong=7, threshold=0.0) glp = Filter.GaussianLowPass( sigma=(1, 0, 0), is_volume=True ) clip1 = Filter.Clip(p_min=50, p_max=100) clip2 = Filter.Clip(p_min=99, p_max=100, is_volume=True) clip1.run(img, in_place=True) bandpass.run(img, in_place=True) glp.run(img, in_place=True) clip2.run(img, in_place=True) tlmpf = FindSpots.TrackpyLocalMaxPeakFinder( spot_diameter=5, # must be odd integer min_mass=0.02,
}, log=True, bins=50, ax=ax3) fig.tight_layout() fig.suptitle(title) # View distribution of intensities in round 1 plot_intensity_histograms(stack=stack, r=1, title='Distribution before clipping') # Clip imagestack without setting is_volume to True bad_clipper = Filter.ClipPercentileToZero(p_min=90, p_max=99.99, level_method=Levels.SCALE_BY_CHUNK) bad_stack = bad_clipper.run(stack) # View distribution if you forget to set is_volume plot_intensity_histograms( bad_stack, r=1, title='Distribution after clipping with is_volume=False') # Clip imagestack without setting is_volume to True clipper = Filter.ClipPercentileToZero(p_min=90, p_max=99.99, is_volume=True, level_method=Levels.SCALE_BY_CHUNK) clipper.run(stack, in_place=True) # View distribution
data using :py:class:`.PerRoundMaxChannel`. """ # Load in situ sequencing experiment and find spots from starfish.image import ApplyTransform, LearnTransform, Filter from starfish.types import Axes, TraceBuildingStrategies from starfish import data, FieldOfView from starfish.spots import FindSpots experiment = data.ISS() fov = experiment.fov() imgs = fov.get_image(FieldOfView.PRIMARY_IMAGES) # primary images dots = fov.get_image("dots") # reference round for image registration # filter raw data masking_radius = 15 filt = Filter.WhiteTophat(masking_radius, is_volume=False) filt.run(imgs, in_place=True) filt.run(dots, in_place=True) # register primary images to reference round learn_translation = LearnTransform.Translation(reference_stack=dots, axes=Axes.ROUND, upsampling=1000) transforms_list = learn_translation.run( imgs.reduce({Axes.CH, Axes.ZPLANE}, func="max")) warp = ApplyTransform.Warp() warp.run(imgs, transforms_list=transforms_list, in_place=True) # run blob detector on dots (reference image with every spot) bd = FindSpots.BlobDetector( min_sigma=1,
#### Load copy number benchmark results # EPY: END markdown # EPY: START code cnts_benchmark = pd.read_csv( 'https://d2nhj9g34unfro.cloudfront.net/20181005/DARTFISH/fov_001/counts.csv' ) cnts_benchmark.head() # EPY: END code # EPY: START markdown #### Filter Image Stack # EPY: END markdown # EPY: START code sc_filt = Filter.ScaleByPercentile(p=100) z_filt = Filter.ZeroByChannelMagnitude(thresh=.05, normalize=False) norm_stack = sc_filt.run(stack) zero_norm_stack = z_filt.run(norm_stack) # EPY: END code # EPY: START markdown ##### Visualize barcode magnitudes to help determine an appropriate threshold for decoding # EPY: END markdown # EPY: START code def compute_magnitudes(stack, norm_order=2):
imgs = experiment["fov_000"].get_image(FieldOfView.PRIMARY_IMAGES) print(imgs) # EPY: END code # EPY: START markdown ### Filter and Visualize Data # EPY: END markdown # EPY: START markdown #First, we remove background signal using a gaussian high-pass filter # EPY: END markdown # EPY: START code from starfish.image import Filter filter_ghp = Filter.GaussianHighPass(sigma=(1, 8, 8), is_volume=True) imgs_ghp = filter_ghp.run(imgs, in_place=False) # EPY: END code # EPY: START markdown #Next, we enhance the spots by filtering with a Laplace filter # EPY: END markdown # EPY: START code filter_laplace = Filter.Laplace(sigma=(0.2, 0.5, 0.5), is_volume=True) imgs_ghp_laplace = filter_laplace.run(imgs_ghp, in_place=False) # EPY: END code # EPY: START markdown #Finally, we take a maximum projection over z, which effectively mitigates effects of out of focus z-planes # EPY: END markdown
# background values. import starfish import starfish.data from starfish.image import Filter from starfish.types import Axes experiment: starfish.Experiment = starfish.data.ISS(use_test_data=True) field_of_view: starfish.FieldOfView = experiment["fov_001"] image: starfish.ImageStack = field_of_view.get_image("primary") ################################################################################################### # Next, create the clip filter. Here we clip at the 50th percentile, optimally separates the spots # from the background clip_50 = Filter.Clip(p_min=97) clipped: starfish.ImageStack = clip_50.run(image) ################################################################################################### # plot both images import matplotlib.pyplot as plt import xarray as xr # get the images orig_plot: xr.DataArray = image.sel({Axes.CH: 0, Axes.ROUND: 0}).xarray.squeeze() clip_plot: xr.DataArray = clipped.sel({Axes.CH: 0, Axes.ROUND: 0}).xarray.squeeze() f, (ax1, ax2) = plt.subplots(ncols=2) ax1.imshow(orig_plot) ax1.set_title("original")
""" import matplotlib.pyplot as plt import numpy as np from copy import deepcopy from starfish import data, FieldOfView, display from starfish.image import Filter from starfish.spots import DetectPixels from starfish.types import Axes, Features, Levels # Load MERFISH data experiment = data.MERFISH(use_test_data=True) imgs = experiment.fov().get_image(FieldOfView.PRIMARY_IMAGES) # filter and deconvolve data ghp = Filter.GaussianHighPass(sigma=3) dpsf = Filter.DeconvolvePSF(num_iter=15, sigma=2, level_method=Levels.SCALE_SATURATED_BY_CHUNK) glp = Filter.GaussianLowPass(sigma=1) ghp.run(imgs, in_place=True) dpsf.run(imgs, in_place=True) glp.run(imgs, in_place=True) # scale data with user-defined factors to normalize images. For this data set, the scale factors # are stored in experiment.json. 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]
#from this notebook. # EPY: END markdown # EPY: START markdown #Project into 2D #--------------- #BaristaSeq is typically processed in 2d. Starfish allows users to reduce data using arbitrary #methods via `starfish.image.Filter.Reduce`. Here we max project Z for both the nissl images and #the primary images. # EPY: END markdown # EPY: START code from starfish.image import Filter from starfish.types import FunctionSource max_projector = Filter.Reduce((Axes.ZPLANE, ), func="max", module=FunctionSource.np) z_projected_image = max_projector.run(img) z_projected_nissl = max_projector.run(nissl) # show the projected data f, (ax1, ax2) = plt.subplots(ncols=2) imshow_plane(img, sel=plane_selector, ax=ax1, title="primary image") imshow_plane(nissl, sel=plane_selector, ax=ax2, title="nissl image") # EPY: END code # EPY: START markdown #Correct Channel Misalignment #---------------------------- #There is a slight miss-alignment of the C channel in the microscope used to #acquire the data. This has been corrected for this data, but here is how it
- run accepts a `verbose` parameter, which triggers tqdm to print progress To add a new filter, simply add default parameters for the constructor (omit is_volume), and it will be tested against the contract by way of registration to the FilterAlgorithmBase """ from typing import Dict import numpy as np import pytest from starfish import ImageStack from starfish.image import Filter methods: Dict = Filter._algorithm_to_class_map() def generate_default_data(): data = np.random.rand(2, 2, 2, 40, 50).astype(np.float32) return ImageStack.from_numpy_array(data) @pytest.mark.parametrize('filter_class', methods.values()) def test_all_methods_adhere_to_contract(filter_class): """Test that all filter algorithms adhere to the filtering contract""" default_kwargs = filter_class._DEFAULT_TESTING_PARAMETERS # accept boolean is_volume instance = filter_class(is_volume=True, **default_kwargs)
# EPY: START code nuclei = fov.get_image("nuclei") nuclei_single_plane = nuclei.reduce({Axes.ROUND, Axes.CH, Axes.ZPLANE}, func="max") imshow_plane(nuclei_single_plane, title="Nuclei (DAPI) channel") # EPY: END code # EPY: START markdown ### Filter raw data before decoding into spatially resolved gene expression # #A White-Tophat filter can be used to enhance spots while minimizing background autoflourescence. The ```masking_radius``` parameter specifies the expected radius, in pixels, of each spot. # EPY: END markdown # EPY: START code # filter raw data masking_radius = 15 filt = Filter.WhiteTophat(masking_radius, is_volume=False) filtered_imgs = filt.run(imgs, verbose=True, in_place=False) filt.run(dots, verbose=True, in_place=True) filt.run(nuclei, verbose=True, in_place=True) # EPY: END code # EPY: START code single_plane_filtered = filtered_imgs.sel(sel) f, (ax1, ax2) = plt.subplots(ncols=2) vmin, vmax = np.percentile(single_plane.xarray.values.data, [5, 99]) imshow_plane( single_plane, ax=ax1, vmin=vmin, vmax=vmax, title="Original data\nRound: 0, Channel: 0" )