def _cli(ctx, input, output, codebook): ctx.obj = dict( component=Decoder, input=input, output=output, intensities=IntensityTable.load(input), codebook=Codebook.from_json(codebook), )
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), )
def _cli(ctx, input, output, blobs_stack, reference_image_from_max_projection, codebook): 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)
def _cli(cls, args, print_help=False): """Runs the decoder component based on parsed arguments.""" if args.decoder_algorithm_class is None or print_help: cls.decoder_group.print_help() cls.decoder_group.exit(status=2) instance = args.decoder_algorithm_class(**vars(args)) # load intensities and codebook intensities = IntensityTable.load(args.input) codebook = Codebook.from_json(args.codebook) # decode and save output intensities = instance.run(intensities, codebook) intensities.save(args.output)
def run(self, intensities: IntensityTable, codebook: Codebook, *args) -> IntensityTable: """Decode spots by selecting the max-valued channel in each sequencing round Parameters ---------- intensities : IntensityTable IntensityTable to be decoded codebook : Codebook Contains codes to decode IntensityTable Returns ------- IntensityTable : IntensityTable decoded and appended with Features.TARGET and Features.QUALITY values. """ return codebook.decode_per_round_max(intensities)
def from_json(cls, json_url: str, strict: bool = None, config: Optional[Union[str, Dict]] = None) -> "Experiment": """ Construct an `Experiment` from an experiment.json file format specifier Parameters ---------- json_url : str file path or web link to an experiment.json file strict : bool if true, then all JSON loaded by this method will be passed to the appropriate validator config : str or dict configuration property that will be passed to starfish.util.config.Config STARISH_CONFIG : This parameter is read from the environment to permit setting configuration values either directly or via a file. Keys read include: - cache.allow_caching STARFISH_STRICT_LOADING : This parameter is read from the environment. If set, then all JSON loaded by this method will be passed to the appropriate validator. The `strict` parameter to this method has priority over the environment variable. Returns ------- Experiment : Experiment object serving the requested experiment data """ if strict is None: strict = "STARFISH_STRICT_LOADING" in os.environ if strict: valid = validate_sptx.validate(json_url) if not valid: raise Exception("validation failed") config_obj = Config(config) # STARFISH_CONFIG is assumed allow_caching = config_obj.lookup(["cache", "allow_caching"], True) backend, name, baseurl = resolve_path_or_url(json_url, allow_caching) with backend.read_contextmanager(name) as fh: experiment_document = json.load(fh) version = cls.verify_version(experiment_document['version']) _, codebook_name, codebook_baseurl = resolve_url( experiment_document['codebook'], baseurl, allow_caching) codebook_absolute_url = pathjoin(codebook_baseurl, codebook_name) codebook = Codebook.from_json(codebook_absolute_url) extras = experiment_document['extras'] fovs: MutableSequence[FieldOfView] = list() fov_tilesets: MutableMapping[str, TileSet] = dict() if version < Version("5.0.0"): primary_image: Collection = Reader.parse_doc( experiment_document['primary_images'], baseurl) auxiliary_images: MutableMapping[str, Collection] = dict() for aux_image_type, aux_image_url in experiment_document[ 'auxiliary_images'].items(): auxiliary_images[aux_image_type] = Reader.parse_doc( aux_image_url, baseurl) for fov_name, primary_tileset in primary_image.all_tilesets(): fov_tilesets[FieldOfView.PRIMARY_IMAGES] = primary_tileset for aux_image_type, aux_image_collection in auxiliary_images.items( ): aux_image_tileset = aux_image_collection.find_tileset( fov_name) if aux_image_tileset is not None: fov_tilesets[aux_image_type] = aux_image_tileset fov = FieldOfView(fov_name, image_tilesets=fov_tilesets) fovs.append(fov) else: images: MutableMapping[str, Collection] = dict() all_fov_names: MutableSet[str] = set() for image_type, image_url in experiment_document['images'].items(): image = Reader.parse_doc(image_url, baseurl) images[image_type] = image for fov_name, _ in image.all_tilesets(): all_fov_names.add(fov_name) for fov_name in all_fov_names: for image_type, image_collection in images.items(): image_tileset = image_collection.find_tileset(fov_name) if image_tileset is not None: fov_tilesets[image_type] = image_tileset fov = FieldOfView(fov_name, image_tilesets=fov_tilesets) fovs.append(fov) return Experiment(fovs, codebook, extras, src_doc=experiment_document)
def write_experiment_json( path: str, fov_count: int, tile_format: ImageFormat, *, primary_image_dimensions: Mapping[Union[str, Axes], int], aux_name_to_dimensions: Mapping[str, Mapping[Union[str, Axes], int]], primary_tile_fetcher: Optional[TileFetcher]=None, aux_tile_fetcher: Optional[Mapping[str, TileFetcher]]=None, postprocess_func: Optional[Callable[[dict], dict]]=None, default_shape: Optional[Mapping[Axes, int]]=None, dimension_order: Sequence[Axes]=(Axes.ZPLANE, Axes.ROUND, Axes.CH), ) -> None: """ Build and returns a top-level experiment description with the following characteristics: Parameters ---------- path : str Directory to write the files to. fov_count : int Number of fields of view in this experiment. primary_image_dimensions : Mapping[Union[str, Axes], int] Dictionary mapping dimension name to dimension size for the primary image. aux_name_to_dimensions : Mapping[str, Mapping[Union[str, Axes], int]] Dictionary mapping the auxiliary image type to dictionaries, which map from dimension name to dimension size. primary_tile_fetcher : Optional[TileFetcher] TileFetcher for primary images. Set this if you want specific image data to be set for the primary images. If not provided, the image data is set to random noise via :class:`RandomNoiseTileFetcher`. aux_tile_fetcher : Optional[Mapping[str, TileFetcher]] TileFetchers for auxiliary images. Set this if you want specific image data to be set for one or more aux image types. If not provided for any given aux image, the image data is set to random noise via :class:`RandomNoiseTileFetcher`. postprocess_func : Optional[Callable[[dict], dict]] If provided, this is called with the experiment document for any postprocessing. An example of this would be to add something to one of the top-level extras field. The callable should return what is to be written as the experiment document. default_shape : Optional[Tuple[int, int]] (default = None) Default shape for the tiles in this experiment. dimension_order : Sequence[Axes] Ordering for which dimensions vary, in order of the slowest changing dimension to the fastest. For instance, if the order is (ROUND, Z, CH) and each dimension has size 2, then the sequence is: (ROUND=0, CH=0, Z=0) (ROUND=0, CH=1, Z=0) (ROUND=0, CH=0, Z=1) (ROUND=0, CH=1, Z=1) (ROUND=1, CH=0, Z=0) (ROUND=1, CH=1, Z=0) (ROUND=1, CH=0, Z=1) (ROUND=1, CH=1, Z=1) (default = (Axes.Z, Axes.ROUND, Axes.CH)) """ if primary_tile_fetcher is None: primary_tile_fetcher = tile_fetcher_factory(RandomNoiseTile) if aux_tile_fetcher is None: aux_tile_fetcher = {} if postprocess_func is None: postprocess_func = lambda doc: doc experiment_doc: Dict[str, Any] = { 'version': str(CURRENT_VERSION), 'images': {}, 'extras': {}, } primary_image = build_image( range(fov_count), range(primary_image_dimensions[Axes.ROUND]), range(primary_image_dimensions[Axes.CH]), range(primary_image_dimensions[Axes.ZPLANE]), primary_tile_fetcher, axes_order=dimension_order, default_shape=default_shape, ) Writer.write_to_path( primary_image, os.path.join(path, "primary_images.json"), pretty=True, partition_path_generator=_fov_path_generator, tile_opener=_tile_opener, tile_format=tile_format, ) experiment_doc['images']['primary'] = "primary_images.json" for aux_name, aux_dimensions in aux_name_to_dimensions.items(): if aux_dimensions is None: continue auxiliary_image = build_image( range(fov_count), range(aux_dimensions[Axes.ROUND]), range(aux_dimensions[Axes.CH]), range(aux_dimensions[Axes.ZPLANE]), aux_tile_fetcher.get(aux_name, tile_fetcher_factory(RandomNoiseTile)), axes_order=dimension_order, default_shape=default_shape, ) Writer.write_to_path( auxiliary_image, os.path.join(path, "{}.json".format(aux_name)), pretty=True, partition_path_generator=_fov_path_generator, tile_opener=_tile_opener, tile_format=tile_format, ) experiment_doc['images'][aux_name] = "{}.json".format(aux_name) experiment_doc["codebook"] = "codebook.json" codebook_array = [ { "codeword": [ {"r": 0, "c": 0, "v": 1}, ], "target": "PLEASE_REPLACE_ME" }, ] codebook = Codebook.from_code_array(codebook_array) codebook_json_filename = "codebook.json" codebook.to_json(os.path.join(path, codebook_json_filename)) experiment_doc = postprocess_func(experiment_doc) with open(os.path.join(path, "experiment.json"), "w") as fh: json.dump(experiment_doc, fh, indent=4)
def loaded_codebook(simple_codebook_json): return Codebook.from_json(simple_codebook_json, n_ch=2, n_round=2)
def simple_codebook_json(simple_codebook_array) -> Generator[str, None, None]: with tempfile.NamedTemporaryFile() as tf: codebook = Codebook.from_code_array(simple_codebook_array) codebook.to_json(tf.name) yield tf.name
def from_json(cls, json_url: str) -> "Experiment": """ Construct an `Experiment` from an experiment.json file format specifier. Loads configuration from StarfishConfig. Parameters ---------- json_url : str file path or web link to an experiment.json file Returns ------- Experiment : Experiment object serving the requested experiment data """ config = StarfishConfig() if config.strict: valid = validate_sptx.validate(json_url) if not valid: raise Exception("validation failed") backend, name, baseurl = resolve_path_or_url(json_url, config.slicedimage) with backend.read_contextmanager(name) as fh: experiment_document = json.load(fh) version = cls.verify_version(experiment_document['version']) _, codebook_name, codebook_baseurl = resolve_url( experiment_document['codebook'], baseurl, config.slicedimage) codebook_absolute_url = pathjoin(codebook_baseurl, codebook_name) codebook = Codebook.from_json(codebook_absolute_url) extras = experiment_document['extras'] fovs: MutableSequence[FieldOfView] = list() fov_tilesets: MutableMapping[str, TileSet] if version < Version("5.0.0"): primary_image: Collection = Reader.parse_doc( experiment_document['primary_images'], baseurl, config.slicedimage) auxiliary_images: MutableMapping[str, Collection] = dict() for aux_image_type, aux_image_url in experiment_document[ 'auxiliary_images'].items(): auxiliary_images[aux_image_type] = Reader.parse_doc( aux_image_url, baseurl, config.slicedimage) for fov_name, primary_tileset in primary_image.all_tilesets(): fov_tilesets = dict() fov_tilesets[FieldOfView.PRIMARY_IMAGES] = primary_tileset for aux_image_type, aux_image_collection in auxiliary_images.items( ): aux_image_tileset = aux_image_collection.find_tileset( fov_name) if aux_image_tileset is not None: fov_tilesets[aux_image_type] = aux_image_tileset fov = FieldOfView(fov_name, image_tilesets=fov_tilesets) fovs.append(fov) else: images: MutableMapping[str, Collection] = dict() all_fov_names: MutableSet[str] = set() for image_type, image_url in experiment_document['images'].items(): image = Reader.parse_doc(image_url, baseurl, config.slicedimage) images[image_type] = image for fov_name, _ in image.all_tilesets(): all_fov_names.add(fov_name) for fov_name in all_fov_names: fov_tilesets = dict() for image_type, image_collection in images.items(): image_tileset = image_collection.find_tileset(fov_name) if image_tileset is not None: fov_tilesets[image_type] = image_tileset fov = FieldOfView(fov_name, image_tilesets=fov_tilesets) fovs.append(fov) return Experiment(fovs, codebook, extras, src_doc=experiment_document)
def codebook(self) -> Codebook: return Codebook.synthetic_one_hot_codebook(self.n_round, self.n_ch, self.n_codes)
def load(self, input_parameter: str) -> Codebook: return Codebook.from_json(input_parameter)
def from_json(cls, json_url: str, strict: bool=None) -> "Experiment": """ Construct an `Experiment` from an experiment.json file format specifier Parameters ---------- json_url : str file path or web link to an experiment.json file strict : bool if true, then all JSON loaded by this method will be passed to the appropriate validator Returns ------- Experiment : Experiment object serving the requested experiment data Environment variables --------------------- STARFISH_STRICT_LOADING : If set, then all JSON loaded by this method will be passed to the appropriate validator. The `strict` parameter to this method has priority over the environment variable. """ if strict is None: strict = "STARFISH_STRICT_LOADING" in os.environ if strict: valid = validate_sptx.validate(json_url) if not valid: raise Exception("validation failed") backend, name, baseurl = resolve_path_or_url(json_url) with backend.read_contextmanager(name) as fh: experiment_document = json.load(fh) cls.verify_version(experiment_document['version']) _, codebook_name, codebook_baseurl = resolve_url(experiment_document['codebook'], baseurl) codebook_absolute_url = pathjoin(codebook_baseurl, codebook_name) codebook = Codebook.from_json(codebook_absolute_url) extras = experiment_document['extras'] primary_image: Collection = Reader.parse_doc(experiment_document['primary_images'], baseurl) auxiliary_images: MutableMapping[str, Collection] = dict() for aux_image_type, aux_image_url in experiment_document['auxiliary_images'].items(): auxiliary_images[aux_image_type] = Reader.parse_doc(aux_image_url, baseurl) fovs: MutableSequence[FieldOfView] = list() for fov_name, primary_tileset in primary_image.all_tilesets(): aux_image_tilesets_for_fov: MutableMapping[str, TileSet] = dict() for aux_image_type, aux_image_collection in auxiliary_images.items(): aux_image_tileset = aux_image_collection.find_tileset(fov_name) if aux_image_tileset is not None: aux_image_tilesets_for_fov[aux_image_type] = aux_image_tileset fov = FieldOfView( fov_name, primary_image_tileset=primary_tileset, auxiliary_image_tilesets=aux_image_tilesets_for_fov, ) fovs.append(fov) return Experiment(fovs, codebook, extras, src_doc=experiment_document)