def create_intensity_table_with_coords(area: Area, n_spots: int = 10) -> IntensityTable: """ Creates a 50X50 intensity table with physical coordinates within the given Area. Parameters ---------- area: Area The area of physical space the IntensityTable should be defined over n_spots: Number of spots to add to the IntensityTable """ codebook = factories.codebook_array_factory() it = IntensityTable.synthetic_intensities(codebook, num_z=1, height=50, width=50, n_spots=n_spots) # intensity table 1 has 10 spots, xmin = 0, ymin = 0, xmax = 2, ymax = 1 it[Coordinates.X.value] = xr.DataArray(np.linspace(area.min_x, area.max_x, n_spots), dims=Features.AXIS) it[Coordinates.Y.value] = xr.DataArray(np.linspace(area.min_y, area.max_y, n_spots), dims=Features.AXIS) return it
def intensities(self, codebook=None) -> IntensityTable: if codebook is None: codebook = self.codebook() intensities = IntensityTable.synthetic_intensities( codebook, self.n_z, self.height, self.width, self.n_spots, self.mean_fluor_per_spot, self.mean_photons_per_fluor) assert intensities.dtype == np.float32 and intensities.max() <= 1 return intensities
def synthetic_decoded_intensity_table( codebook, num_z: int = 12, height: int = 50, width: int = 40, n_spots: int = 10, mean_fluor_per_spot: int = 200, mean_photons_per_fluor: int = 50, ) -> DecodedIntensityTable: """ Creates an IntensityTable with synthetic spots, that correspond to valid codes in a provided codebook. Parameters ---------- codebook : Codebook Starfish codebook object. num_z : int Number of z-planes to use when localizing spots. height : int y dimension of each synthetic plane. width : int x dimension of each synthetic plane. n_spots : int Number of spots to generate. mean_fluor_per_spot : int Mean number of fluorophores per spot. mean_photons_per_fluor : int Mean number of photons per fluorophore. Returns ------- DecodedIntensityTable """ intensities = IntensityTable.synthetic_intensities( codebook, num_z=num_z, height=height, width=width, n_spots=n_spots, mean_fluor_per_spot=mean_fluor_per_spot, mean_photons_per_fluor=mean_photons_per_fluor) targets = np.random.choice(codebook.coords[Features.TARGET], size=n_spots, replace=True) return DecodedIntensityTable.from_intensity_table(intensities, targets=(Features.AXIS, targets))
def test_tranfering_physical_coords_to_intensity_table(): stack_shape = OrderedDict([(Axes.ROUND, 3), (Axes.CH, 2), (Axes.ZPLANE, 1), (Axes.Y, 50), (Axes.X, 40)]) physical_coords = OrderedDict([(PhysicalCoordinateTypes.X_MIN, 1), (PhysicalCoordinateTypes.X_MAX, 2), (PhysicalCoordinateTypes.Y_MIN, 4), (PhysicalCoordinateTypes.Y_MAX, 6), (PhysicalCoordinateTypes.Z_MIN, 1), (PhysicalCoordinateTypes.Z_MAX, 3)]) stack = factories.imagestack_with_coords_factory(stack_shape, physical_coords) codebook = factories.codebook_array_factory() intensities = IntensityTable.synthetic_intensities( codebook, num_z=stack_shape[Axes.ZPLANE], height=stack_shape[Axes.Y], width=stack_shape[Axes.X], n_spots=NUMBER_SPOTS) intensities = intensity_table_coordinates.\ transfer_physical_coords_from_imagestack_to_intensity_table(stack, intensities) # Assert that new cords were added xc = intensities.coords[Coordinates.X] yc = intensities.coords[Coordinates.Y] zc = intensities.coords[Coordinates.Z] assert xc.size == NUMBER_SPOTS assert yc.size == NUMBER_SPOTS assert zc.size == NUMBER_SPOTS # Assert that the physical coords align with their corresponding pixel coords for spot in xc.features: pixel_x = spot[Axes.X.value].data physical_x = stack.xarray[Coordinates.X.value][pixel_x] assert np.isclose(spot[Coordinates.X.value], physical_x) for spot in yc.features: pixel_y = spot[Axes.Y.value].data physical_y = stack.xarray[Coordinates.Y.value][pixel_y] assert np.isclose(spot[Coordinates.Y.value], physical_y) # Assert that zc value is middle of z range for spot in zc.features: z_plane = spot[Axes.ZPLANE.value].data physical_z = stack.xarray[Coordinates.Z.value][z_plane] assert np.isclose(spot[Coordinates.Z.value], physical_z)
def test_tranfering_physical_coords_to_expression_matrix(): stack_shape = OrderedDict([(Axes.ROUND, 3), (Axes.CH, 2), (Axes.ZPLANE, 1), (Axes.Y, 50), (Axes.X, 40)]) physical_coords = OrderedDict([(PhysicalCoordinateTypes.X_MIN, 1), (PhysicalCoordinateTypes.X_MAX, 2), (PhysicalCoordinateTypes.Y_MIN, 4), (PhysicalCoordinateTypes.Y_MAX, 6), (PhysicalCoordinateTypes.Z_MIN, 1), (PhysicalCoordinateTypes.Z_MAX, 3)]) stack = factories.imagestack_with_coords_factory(stack_shape, physical_coords) codebook = factories.codebook_array_factory() intensities = IntensityTable.synthetic_intensities( codebook, num_z=stack_shape[Axes.ZPLANE], height=stack_shape[Axes.Y], width=stack_shape[Axes.X], n_spots=NUMBER_SPOTS) intensities = intensity_table_coordinates. \ transfer_physical_coords_from_imagestack_to_intensity_table(stack, intensities) # Check that error is thrown before target assignment try: intensities.to_expression_matrix() except KeyError as e: # Assert value error is thrown with right message assert e.args[0] == "IntensityTable must have 'cell_id' assignments for each cell before " \ "this function can be called. See starfish.TargetAssignment.Label." # mock out come cell_ids cell_ids = random.sample(range(1, 20), NUMBER_SPOTS) intensities[Features.CELL_ID] = (Features.AXIS, cell_ids) expression_matrix = intensities.to_expression_matrix() # Assert that coords were transferred xc = expression_matrix.coords[Coordinates.X] yc = expression_matrix.coords[Coordinates.Y] zc = expression_matrix.coords[Coordinates.Z] assert xc.size == len(set(cell_ids)) assert yc.size == len(set(cell_ids)) assert zc.size == len(set(cell_ids))
def dummy_intensities() -> IntensityTable: codebook = test_utils.codebook_array_factory() intensities = IntensityTable.synthetic_intensities( codebook, num_z=10, height=10, width=10, n_spots=5, ) intensities[Coordinates.Z.value] = (Features.AXIS, [0, 1, 0, 1, 0]) intensities[Coordinates.Y.value] = (Features.AXIS, [10, 30, 50, 40, 20]) intensities[Coordinates.X.value] = (Features.AXIS, [50.2, 30.2, 60.2, 40.2, 70.2]) # remove target from dummy to test error messages del intensities[Features.TARGET] return intensities
def test_save_expression_matrix(): codebook = codebook_array_factory() intensities = IntensityTable.synthetic_intensities( codebook, num_z=3, height=100, width=100, n_spots=10 ) # mock out come cell_ids cell_ids = random.sample(range(1, 20), NUMBER_SPOTS) intensities[Features.CELL_ID] = (Features.AXIS, cell_ids) expression_matrix = intensities.to_expression_matrix() # test all saving methods expression_matrix.save("expression")
def test_synthetic_intensity_generation(): """ Create a 2-spot IntensityTable of pixel size (z=3, y=4, x=5) from a codebook with 3 channels and 2 rounds. Verify that the constructed Synthetic IntensityTable conforms to those dimensions, and given a known random seed, that the output spots decode to match a target in the input Codebook """ # set seed to check that codebook is matched. This seed generates 2 instances of GENE_B np.random.seed(1) codebook = test_utils.codebook_array_factory() num_z, height, width = 3, 4, 5 intensities = IntensityTable.synthetic_intensities(codebook, num_z=num_z, height=height, width=width, n_spots=2) # sizes should match codebook assert intensities.sizes[Axes.ROUND] == 2 assert intensities.sizes[Axes.CH] == 3 assert intensities.sizes[Features.AXIS] == 2 # attributes should be bounded by the specified size assert np.all(intensities[Axes.ZPLANE.value] <= num_z) assert np.all(intensities[Axes.Y.value] <= height) assert np.all(intensities[Axes.X.value] <= width) # both codes should match GENE_B assert np.array_equal( np.where(intensities.values), [ [0, 0, 1, 1], # two each in feature 0 & 1 [1, 2, 1, 2], # one each in channel 1 & 2 [1, 0, 1, 0] ], # channel 1 matches round 1, channel 2 matches round zero )
def test_tranfering_physical_coords_to_intensity_table(): stack_shape = OrderedDict([(Axes.ROUND, 3), (Axes.CH, 2), (Axes.ZPLANE, 1), (Axes.Y, 50), (Axes.X, 40)]) physical_coords = OrderedDict([(PhysicalCoordinateTypes.X_MIN, 1), (PhysicalCoordinateTypes.X_MAX, 2), (PhysicalCoordinateTypes.Y_MIN, 4), (PhysicalCoordinateTypes.Y_MAX, 6), (PhysicalCoordinateTypes.Z_MIN, 1), (PhysicalCoordinateTypes.Z_MAX, 3)]) stack = test_utils.imagestack_with_coords_factory(stack_shape, physical_coords) codebook = test_utils.codebook_array_factory() intensities = IntensityTable.synthetic_intensities( codebook, num_z=stack_shape[Axes.ZPLANE], height=stack_shape[Axes.Y], width=stack_shape[Axes.X], n_spots=NUMBER_SPOTS ) intensities = intensity_table_coordinates.\ transfer_physical_coords_from_imagestack_to_intensity_table(stack, intensities) # Assert that new cords were added xc = intensities.coords[Coordinates.X] yc = intensities.coords[Coordinates.Y] zc = intensities.coords[Coordinates.Z] assert xc.size == NUMBER_SPOTS assert yc.size == NUMBER_SPOTS assert zc.size == NUMBER_SPOTS physical_pixel_size_x = physical_coordinate_calculator._calculate_physical_pixel_size( coord_min=physical_coords[PhysicalCoordinateTypes.X_MIN], coord_max=physical_coords[PhysicalCoordinateTypes.X_MAX], num_pixels=stack_shape[Axes.X]) physical_pixel_size_y = physical_coordinate_calculator._calculate_physical_pixel_size( coord_min=physical_coords[PhysicalCoordinateTypes.Y_MIN], coord_max=physical_coords[PhysicalCoordinateTypes.Y_MAX], num_pixels=stack_shape[Axes.Y]) # Assert that the physical coords align with their corresponding pixel coords for spot in xc.features: pixel_x = spot[Axes.X.value].data physical_x = spot[Coordinates.X.value].data calculated_pixel = physical_cord_to_pixel_value(physical_x, physical_pixel_size_x, physical_coords[ PhysicalCoordinateTypes.X_MIN ]) assert np.isclose(pixel_x, calculated_pixel) for spot in yc.features: pixel_y = spot[Axes.Y.value].data physical_y = spot[Coordinates.Y.value].data calculated_pixel = physical_cord_to_pixel_value(physical_y, physical_pixel_size_y, physical_coords[ PhysicalCoordinateTypes.Y_MIN ]) assert np.isclose(pixel_y, calculated_pixel) # Assert that zc value is middle of z range for spot in zc.features: physical_z = spot[Coordinates.Z.value].data assert np.isclose(physical_coords[PhysicalCoordinateTypes.Z_MAX], (physical_z * 2) - physical_coords[PhysicalCoordinateTypes.Z_MIN])
def synthetic_intensity_table() -> IntensityTable: return IntensityTable.synthetic_intensities(loaded_codebook(), n_spots=2)