コード例 #1
0
ファイル: __init__.py プロジェクト: nicopierson/starfish
class Decoder(PipelineComponent):
    @classmethod
    def _get_algorithm_base_class(cls) -> Type[AlgorithmBase]:
        return _base.DecoderAlgorithmBase

    @classmethod
    def _cli_run(cls, ctx, instance):
        table = ctx.obj["intensities"]
        codes = ctx.obj["codebook"]
        output = ctx.obj["output"]
        intensities = instance.run(table, codes)
        intensities.save(output)

    @staticmethod
    @click.group("decode")
    @click.option("-i", "--input", required=True, type=click.Path(exists=True))
    @click.option("-o", "--output", required=True)
    @click.option("--codebook", required=True, type=click.Path(exists=True))
    @click.pass_context
    def _cli(ctx, input, output, codebook):
        """assign genes to spots"""
        ctx.obj = dict(
            component=Decoder,
            input=input,
            output=output,
            intensities=IntensityTable.load(input),
            codebook=Codebook.from_json(codebook),
        )
コード例 #2
0
ファイル: __init__.py プロジェクト: Henley13/starfish
class TargetAssignment(PipelineComponent):
    @classmethod
    def _get_algorithm_base_class(cls) -> Type[AlgorithmBase]:
        return TargetAssignmentAlgorithm

    @classmethod
    def _cli_run(cls, ctx, instance):
        output = ctx.obj["output"]
        intensity_table = ctx.obj["intensity_table"]
        label_image = ctx.obj["label_image"]
        assigned = instance.run(label_image, intensity_table)
        print(f"Writing intensities, including cell ids to {output}")
        assigned.save(os.path.join(output))

    @staticmethod
    @click.group("target_assignment")
    @click.option("--label-image", required=True, type=click.Path(exists=True))
    @click.option("--intensities", required=True, type=click.Path(exists=True))
    @click.option("-o", "--output", required=True)
    @click.pass_context
    def _cli(ctx, label_image, intensities, output):
        """assign targets to cells"""

        print('Assigning targets to cells...')
        ctx.obj = dict(component=TargetAssignment,
                       output=output,
                       intensity_table=IntensityTable.load(intensities),
                       label_image=imread(label_image))
コード例 #3
0
class Segmentation(PipelineComponent):
    @classmethod
    def _get_algorithm_base_class(cls) -> Type[AlgorithmBase]:
        return _base.SegmentationAlgorithmBase

    @classmethod
    def _cli_run(cls, ctx, instance):
        output = ctx.obj["output"]
        pri_stack = ctx.obj["primary_images"]
        nuc_stack = ctx.obj["nuclei"]

        label_image = instance.run(pri_stack, nuc_stack)

        print(f"Writing label image to {output}")
        imsave(output, label_image)

    @staticmethod
    @click.group("segment")
    @click.option("--primary-images",
                  required=True,
                  type=click.Path(exists=True))
    @click.option("--nuclei", required=True, type=click.Path(exists=True))
    @click.option("-o", "--output", required=True)
    @click.pass_context
    def _cli(ctx, primary_images, nuclei, output):
        """define polygons for cell boundaries and assign spots"""
        print('Segmenting ...')
        ctx.obj = dict(
            component=Segmentation,
            output=output,
            primary_images=ImageStack.from_path_or_url(primary_images),
            nuclei=ImageStack.from_path_or_url(nuclei),
        )
コード例 #4
0
ファイル: __init__.py プロジェクト: Henley13/starfish
class Registration(PipelineComponent):
    @classmethod
    def _get_algorithm_base_class(cls) -> Type[AlgorithmBase]:
        return _base.RegistrationAlgorithmBase

    @classmethod
    def _cli_run(cls, ctx, instance):
        output = ctx.obj["output"]
        stack = ctx.obj["stack"]
        instance.run(stack)
        stack.export(output)

    @staticmethod
    @click.group("registration")
    @click.option("-i", "--input", type=click.Path(exists=True))
    @click.option("-o", "--output", required=True)
    @click.pass_context
    def _cli(ctx, input, output):
        """translation correction of image stacks"""
        print("Registering...")
        ctx.obj = dict(
            component=Registration,
            input=input,
            output=output,
            stack=ImageStack.from_path_or_url(input),
        )
コード例 #5
0
ファイル: _base.py プロジェクト: ttung/starfish
class ApplyTransform(PipelineComponent):
    @classmethod
    def pipeline_component_type_name(cls) -> str:
        return COMPONENT_NAME

    @classmethod
    def _cli_run(cls, ctx, instance):
        output = ctx.obj["output"]
        stack = ctx.obj["stack"]
        transformation_list = ctx.obj["transformation_list"]
        transformed = instance.run(stack, transformation_list)
        transformed.export(output)

    @staticmethod
    @click.group(COMPONENT_NAME)
    @click.option("-i", "--input", type=ImageStackParamType)
    @click.option("-o", "--output", required=True)
    @click.option(
        "--transformation-list",
        required=True,
        type=click.Path(exists=True),
        help="The list of transformations to apply to the ImageStack.")
    @click.pass_context
    def _cli(ctx, input, output, transformation_list):
        print("Applying Transform to images...")
        ctx.obj = dict(
            component=ApplyTransform,
            output=output,
            stack=input,
            transformation_list=TransformsList.from_json(transformation_list))
コード例 #6
0
class PixelSpotDecoder(PipelineComponent):

    @classmethod
    def _get_algorithm_base_class(cls) -> Type[AlgorithmBase]:
        return _base.PixelDecoderAlgorithmBase

    @classmethod
    def _cli_run(cls, ctx, instance):
        output = ctx.obj["output"]
        image_stack = ctx.obj["image_stack"]
        # TODO ambrosejcarr serialize and save ConnectedComponentDecodingResult somehow
        intensities, ccdr = instance.run(image_stack)
        intensities.save(output)

    @staticmethod
    @click.group("detect_pixels")
    @click.option("-i", "--input", required=True, type=click.Path(exists=True))
    @click.option("-o", "--output", required=True)
    @click.option(
        '--codebook', default=None, required=True, help=(
            'A spaceTx spec-compliant json file that describes a three dimensional tensor '
            'whose values are the expected intensity of a spot for each code in each imaging '
            'round and each color channel.'
        )
    )
    @click.pass_context
    def _cli(ctx, input, output, codebook):
        """pixel-wise spot detection and decoding"""
        print('Detecting Spots ...')
        ctx.obj = dict(
            component=PixelSpotDecoder,
            image_stack=ImageStack.from_path_or_url(input),
            output=output,
            codebook=Codebook.from_json(codebook),
        )
コード例 #7
0
ファイル: __init__.py プロジェクト: Henley13/starfish
class Filter(PipelineComponent):
    @classmethod
    def _get_algorithm_base_class(cls) -> Type[AlgorithmBase]:
        return _base.FilterAlgorithmBase

    @classmethod
    def _cli_run(cls, ctx, instance):
        output = ctx.obj["output"]
        stack = ctx.obj["stack"]
        filtered = instance.run(stack)
        filtered.export(output)

    @staticmethod
    @click.group("filter")
    @click.option("-i", "--input", type=click.Path(exists=True))
    @click.option("-o", "--output", required=True)
    @click.pass_context
    def _cli(ctx, input, output):
        """smooth, sharpen, denoise, etc"""
        print("Filtering images...")
        ctx.obj = dict(
            component=Filter,
            input=input,
            output=output,
            stack=ImageStack.from_path_or_url(input),
        )
コード例 #8
0
class Decoder(PipelineComponent):
    @classmethod
    def pipeline_component_type_name(cls) -> str:
        return COMPONENT_NAME

    @classmethod
    def _cli_run(cls, ctx, instance):
        table = ctx.obj["intensities"]
        codes = ctx.obj["codebook"]
        output = ctx.obj["output"]
        intensities = instance.run(table, codes)
        intensities.save(output)

    @staticmethod
    @click.group(COMPONENT_NAME)
    @click.option("-i", "--input", required=True, type=click.Path(exists=True))
    @click.option("-o", "--output", required=True)
    @click.option("--codebook", required=True, type=CodebookParamType)
    @click.pass_context
    def _cli(ctx, input, output, codebook):
        """assign genes to spots"""
        ctx.obj = dict(
            component=Decoder,
            input=input,
            output=output,
            intensities=IntensityTable.load(input),
            codebook=codebook,
        )
コード例 #9
0
class Filter(PipelineComponent):
    @classmethod
    def pipeline_component_type_name(cls) -> str:
        return COMPONENT_NAME

    @classmethod
    def _cli_run(cls, ctx, instance):
        output = ctx.obj["output"]
        stack = ctx.obj["stack"]
        filtered = instance.run(stack)
        filtered.export(output)

    @staticmethod
    @click.group(COMPONENT_NAME)
    @click.option("-i", "--input", type=click.Path(exists=True))
    @click.option("-o", "--output", required=True)
    @click.pass_context
    def _cli(ctx, input, output):
        """smooth, sharpen, denoise, etc"""
        print("Filtering images...")
        ctx.obj = dict(
            component=Filter,
            input=input,
            output=output,
            stack=ImageStack.from_path_or_url(input),
        )
コード例 #10
0
ファイル: __init__.py プロジェクト: nicopierson/starfish
class SpotFinder(PipelineComponent):

    @classmethod
    def _get_algorithm_base_class(cls) -> Type[AlgorithmBase]:
        return _base.SpotFinderAlgorithmBase

    @classmethod
    def _cli_run(cls, ctx, instance):
        output = ctx.obj["output"]
        blobs_stack = ctx.obj["blobs_stack"]
        image_stack = ctx.obj["image_stack"]
        ref_image = ctx.obj["reference_image_from_max_projection"]
        if blobs_stack is not None:
            blobs_stack = ImageStack.from_path_or_url(blobs_stack)  # type: ignore
            mp = blobs_stack.max_proj(Axes.ROUND, Axes.CH)
            mp_numpy = mp._squeezed_numpy(Axes.ROUND, Axes.CH)
            intensities = instance.run(
                image_stack,
                blobs_image=mp_numpy,
                reference_image_from_max_projection=ref_image,
            )
        else:
            intensities = instance.run(image_stack)

        # When run() returns a tuple, we only save the intensities for now
        # TODO ambrosejcarr find a way to save arbitrary detector results
        if isinstance(intensities, tuple):
            intensities = intensities[0]
        intensities.save(output)

    @staticmethod
    @click.group("detect_spots")
    @click.option("-i", "--input", required=True, type=click.Path(exists=True))
    @click.option("-o", "--output", required=True)
    @click.option(
        '--blobs-stack', default=None, required=False, help=(
            'ImageStack that contains the blobs. Will be max-projected across imaging round '
            'and channel to produce the blobs_image'
        )
    )
    @click.option(
        '--reference-image-from-max-projection', default=False, is_flag=True, help=(
            'Construct a reference image by max projecting imaging rounds and channels. Spots '
            'are found in this image and then measured across all images in the input stack.'
        )
    )
    @click.pass_context
    def _cli(ctx, input, output, blobs_stack, reference_image_from_max_projection):
        """detect spots"""
        print('Detecting Spots ...')
        ctx.obj = dict(
            component=SpotFinder,
            image_stack=ImageStack.from_path_or_url(input),
            output=output,
            blobs_stack=blobs_stack,
            reference_image_from_max_projection=reference_image_from_max_projection,
        )
コード例 #11
0
ファイル: __init__.py プロジェクト: Henley13/starfish
class SpotFinder(PipelineComponent):
    @classmethod
    def _get_algorithm_base_class(cls) -> Type[AlgorithmBase]:
        return _base.SpotFinderAlgorithmBase

    @classmethod
    def _cli_run(cls, ctx, instance):
        output = ctx.obj["output"]
        blobs_stack = ctx.obj["blobs_stack"]
        image_stack = ctx.obj["image_stack"]
        ref_image = ctx.obj["reference_image_from_max_projection"]
        if blobs_stack is not None:
            blobs_stack = ImageStack.from_path_or_url(
                blobs_stack)  # type: ignore
            mp = blobs_stack.max_proj(Axes.ROUND, Axes.CH)
            mp_numpy = mp._squeezed_numpy(Axes.ROUND, Axes.CH)
            #  TODO: this won't work for PixelSpotDectector
            intensities = instance.run(
                image_stack,
                blobs_image=mp_numpy,
                reference_image_from_max_projection=ref_image,
            )
        else:
            intensities = instance.run(image_stack)

        # When PixelSpotDetector is used run() returns a tuple
        if isinstance(intensities, tuple):
            intensities = intensities[0]
        intensities.save(output)

    @staticmethod
    @click.group("detect_spots")
    @click.option("-i", "--input", required=True, type=click.Path(exists=True))
    @click.option("-o", "--output", required=True)
    @click.option(
        '--blobs-stack',
        default=None,
        required=False,
        help=
        ('ImageStack that contains the blobs. Will be max-projected across imaging round '
         'and channel to produce the blobs_image'))
    @click.option(
        '--reference-image-from-max-projection',
        default=False,
        is_flag=True,
        help=
        ('Construct a reference image by max projecting imaging rounds and channels. Spots '
         'are found in this image and then measured across all images in the input stack.'
         ))
    @click.option(
        '--codebook',
        default=None,
        required=False,
        help=
        ('A spaceTx spec-compliant json file that describes a three dimensional tensor '
         'whose values are the expected intensity of a spot for each code in each imaging '
         'round and each color channel.'))
    @click.pass_context
    def _cli(ctx, input, output, blobs_stack,
             reference_image_from_max_projection, codebook):
        """assign spots to regions"""
        print('Detecting Spots ...')
        ctx.obj = dict(
            component=SpotFinder,
            image_stack=ImageStack.from_path_or_url(input),
            output=output,
            blobs_stack=blobs_stack,
            reference_image_from_max_projection=
            reference_image_from_max_projection,
            codebook=None,
        )

        if codebook is not None:
            ctx.obj["codebook"] = Codebook.from_json(codebook)
コード例 #12
0
ファイル: cli.py プロジェクト: ttung/starfish
def dimensions_option(name, required):
    return click.option(
        "--{}-dimensions".format(name),
        type=StarfishIndex(),
        required=required,
        help=
        "Dimensions for the {} images.  Should be a json dict, with {}, {}, "
        "and {} as the possible keys.  The value should be the shape along that "
        "dimension.  If a key is not present, the value is assumed to be 0.".
        format(name, Axes.ROUND.value, Axes.CH.value, Axes.ZPLANE.value))


decorators = [
    click.command(),
    click.argument("output_dir",
                   type=click.Path(exists=True, file_okay=False,
                                   writable=True)),
    click.option("--fov-count",
                 type=int,
                 required=True,
                 help="Number of FOVs in this experiment."),
    dimensions_option("primary-image", True),
]
for image_name in AUX_IMAGE_NAMES:
    decorators.append(dimensions_option(image_name, False))


def build(output_dir, fov_count, primary_image_dimensions, **kwargs):
    """generate synthetic experiments"""
    write_experiment_json(
        output_dir,
        fov_count,
コード例 #13
0
ファイル: fourier_shift.py プロジェクト: nicopierson/starfish
class FourierShiftRegistration(RegistrationAlgorithmBase):
    """
    Implements fourier shift registration.  TODO: (dganguli) FILL IN DETAILS HERE PLS.

    Performs a simple translation registration.

    """
    def __init__(self, upsampling: int,
                 reference_stack: Union[str, ImageStack], **kwargs) -> None:
        """Implements fourier shift registrations, which performs a simple translation registration

        Parameters
        ----------
        upsampling : int
            images are registered to within 1 / upsample_factor of a pixel
        reference_stack : ImageStack
            the ImageStack against which this object will register images

        See Also
        --------
        https://en.wikipedia.org/wiki/Phase_correlation

        """
        self.upsampling = upsampling

        # TODO ambrosejcarr: remove the ability to load from string in the constructor, move to CLI
        if isinstance(reference_stack, ImageStack):
            self.reference_stack = reference_stack
        else:
            self.reference_stack = ImageStack.from_path_or_url(reference_stack)

    def run(self,
            image: ImageStack,
            in_place: bool = False) -> Optional[ImageStack]:
        """Register an ImageStack against a reference image.

        Parameters
        ----------
        image : ImageStack
            The stack to be registered
        in_place : bool
            If false, return a new registered stack. Else, register in-place (default False)

        Returns
        -------


        """

        if not in_place:
            image = deepcopy(image)

        # TODO: (ambrosejcarr) is this the appropriate way of dealing with Z in registration?
        mp = image.max_proj(Axes.CH, Axes.ZPLANE)
        mp_numpy = mp._squeezed_numpy(Axes.CH, Axes.ZPLANE)
        reference_image_mp = self.reference_stack.max_proj(
            Axes.ROUND, Axes.CH, Axes.ZPLANE)
        reference_image_numpy = reference_image_mp._squeezed_numpy(
            Axes.ROUND, Axes.CH, Axes.ZPLANE)

        for r in image.axis_labels(Axes.ROUND):
            # compute shift between maximum projection (across channels) and dots, for each round
            # TODO: make the max projection array ignorant of axes ordering.
            shift, error = compute_shift(mp_numpy[r, :, :],
                                         reference_image_numpy,
                                         self.upsampling)
            print(f"For round: {r}, Shift: {shift}, Error: {error}")

            for c in image.axis_labels(Axes.CH):
                for z in image.axis_labels(Axes.ZPLANE):
                    # apply shift to all zplanes, channels, and imaging rounds
                    selector = {Axes.ROUND: r, Axes.CH: c, Axes.ZPLANE: z}
                    data, axes = image.get_slice(selector=selector)
                    assert len(axes) == 0

                    result = shift_im(data, shift)
                    result = preserve_float_range(result)

                    image.set_slice(selector=selector, data=result)

        if not in_place:
            return image
        return None

    @staticmethod
    @click.command("FourierShiftRegistration")
    @click.option("--upsampling",
                  default=1,
                  type=int,
                  help="Amount of up-sampling")
    @click.option("--reference-stack",
                  required=True,
                  type=click.Path(exists=True),
                  help="The image stack to align the input image stack to.")
    @click.pass_context
    def _cli(ctx, upsampling, reference_stack):
        ctx.obj["component"]._cli_run(
            ctx, FourierShiftRegistration(upsampling, reference_stack))