diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 78278c7d..ce225566 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,7 +45,7 @@ jobs: run: | pytest --cov cellpack/tests/ - name: Upload codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 lint: runs-on: ubuntu-latest diff --git a/cellpack/autopack/Analysis.py b/cellpack/autopack/Analysis.py index 4906c4d4..a631fc73 100644 --- a/cellpack/autopack/Analysis.py +++ b/cellpack/autopack/Analysis.py @@ -828,12 +828,17 @@ def update_distance_distribution_dictionaries( get_angles = False if ingr.packing_mode == "gradient" and self.env.use_gradient: - if not isinstance(ingr.gradient, list): + if isinstance(ingr.gradient, list): + if len(ingr.gradient) > 1 or len(ingr.gradient) == 0: + self.center = center + else: + self.center = center = self.env.gradients[ + ingr.gradient[0] + ].mode_settings.get("center", center) + else: self.center = center = self.env.gradients[ ingr.gradient ].mode_settings.get("center", center) - else: - self.center = center get_angles = True # get angles wrt gradient diff --git a/cellpack/autopack/Environment.py b/cellpack/autopack/Environment.py index 735ed9d4..7ef7eab5 100644 --- a/cellpack/autopack/Environment.py +++ b/cellpack/autopack/Environment.py @@ -1700,28 +1700,9 @@ def getPointToDrop( # get the most probable point using the gradient # use the gradient weighted map and get mot probabl point self.log.info("pick point from gradients %d", (len(allIngrPts))) - if isinstance(ingr.gradient, list) and len(ingr.gradient) > 1: - if not hasattr(ingr, "combined_weight"): - gradient_list = [] - gradient_weights = [] - for (gradient_name, gradient), gradient_weight in zip( - self.gradients.items(), ingr.gradient_weights - ): - if gradient_name in ingr.gradient: - gradient_list.append(gradient) - gradient_weights.append(gradient_weight) - - combined_weight = Gradient.get_combined_gradient_weight( - gradient_list, gradient_weights - ) - ingr.combined_weight = combined_weight - - ptInd = Gradient.pick_point_from_weight( - ingr.combined_weight, allIngrPts - ) - - else: - ptInd = self.gradients[ingr.gradient].pickPoint(allIngrPts) + ptInd = Gradient.pick_point_for_ingredient( + ingr, allIngrPts, self.gradients + ) else: # pick a point randomly among free points # random or uniform? diff --git a/cellpack/autopack/Gradient.py b/cellpack/autopack/Gradient.py index bbf4f932..9ee97126 100644 --- a/cellpack/autopack/Gradient.py +++ b/cellpack/autopack/Gradient.py @@ -101,7 +101,7 @@ def scale_between_0_and_1(values): return (values - min_value) / (max_value - min_value) @staticmethod - def get_combined_gradient_weight(gradient_list, gradient_weights=None): + def get_combined_gradient_weight(gradient_list): """ Combine the gradient weights @@ -119,7 +119,7 @@ def get_combined_gradient_weight(gradient_list, gradient_weights=None): for i in range(len(gradient_list)): weight_list[i] = Gradient.scale_between_0_and_1(gradient_list[i].weight) - combined_weight = numpy.average(weight_list, axis=0, weights=gradient_weights) + combined_weight = numpy.mean(weight_list, axis=0) combined_weight = Gradient.scale_between_0_and_1(combined_weight) return combined_weight @@ -143,8 +143,8 @@ def pick_point_from_weight(weight, points): the index of the picked point """ weights_to_use = numpy.take(weight, points) - weights_to_use[numpy.isnan(weights_to_use)] = 0 weights_to_use = Gradient.scale_between_0_and_1(weights_to_use) + weights_to_use[numpy.isnan(weights_to_use)] = 0 point_probabilities = weights_to_use / numpy.sum(weights_to_use) @@ -152,6 +152,50 @@ def pick_point_from_weight(weight, points): return point + @staticmethod + def pick_point_for_ingredient(ingr, allIngrPts, all_gradients): + """ + Picks a point for an ingredient according to the gradient + + Parameters + ---------- + ingr: Ingredient + the ingredient object + + allIngrPts: numpy.ndarray + list of grid point indices + + all_gradients: dict + dictionary of all gradient objects + + Returns + ---------- + int + the index of the picked point + """ + if isinstance(ingr.gradient, list): + if len(ingr.gradient) > 1: + if not hasattr(ingr, "combined_weight"): + gradient_list = [ + gradient + for gradient_name, gradient in all_gradients.items() + if gradient_name in ingr.gradient + ] + combined_weight = Gradient.get_combined_gradient_weight( + gradient_list + ) + ingr.combined_weight = combined_weight + + ptInd = Gradient.pick_point_from_weight( + ingr.combined_weight, allIngrPts + ) + else: + ptInd = all_gradients[ingr.gradient[0]].pickPoint(allIngrPts) + else: + ptInd = all_gradients[ingr.gradient].pickPoint(allIngrPts) + + return ptInd + def get_center(self): """get the center of the gradient grid""" center = [0.0, 0.0, 0.0] diff --git a/cellpack/autopack/loaders/recipe_loader.py b/cellpack/autopack/loaders/recipe_loader.py index fd21717e..cf0be99b 100644 --- a/cellpack/autopack/loaders/recipe_loader.py +++ b/cellpack/autopack/loaders/recipe_loader.py @@ -132,16 +132,6 @@ def _sanitize_format_version(recipe_data): format_version = recipe_data["format_version"] return format_version - def get_only_recipe_metadata(self): - recipe_meta_data = { - "format_version": self.recipe_data["format_version"], - "version": self.recipe_data["version"], - "name": self.recipe_data["name"], - "bounding_box": self.recipe_data["bounding_box"], - "composition": {}, - } - return recipe_meta_data - def _migrate_version(self, old_recipe): converted = False if old_recipe["format_version"] == "1.0": diff --git a/cellpack/autopack/upy/simularium/simularium_helper.py b/cellpack/autopack/upy/simularium/simularium_helper.py index a87ad5b0..bd09210b 100644 --- a/cellpack/autopack/upy/simularium/simularium_helper.py +++ b/cellpack/autopack/upy/simularium/simularium_helper.py @@ -363,7 +363,10 @@ def add_grid_data_to_scene(self, incoming_name, positions, values, radius=0.5): positions, values = self.sort_values(positions, values) - colormap = matplotlib.cm.Reds(values) + normalized_values = (values - np.min(values)) / ( + np.max(values) - np.min(values) + ) + colormap = matplotlib.cm.Reds(normalized_values) for index, value in enumerate(values): name = f"{incoming_name}#{value:.3f}" diff --git a/cellpack/bin/upload.py b/cellpack/bin/upload.py index 62f1b9f1..9a932ae1 100644 --- a/cellpack/bin/upload.py +++ b/cellpack/bin/upload.py @@ -8,6 +8,25 @@ from cellpack.autopack.loaders.recipe_loader import RecipeLoader +def get_recipe_metadata(loader): + """ + Extracts and returns essential metadata from a recipe for uploading + """ + try: + recipe_meta_data = { + "format_version": loader.recipe_data["format_version"], + "version": loader.recipe_data["version"], + "name": loader.recipe_data["name"], + "bounding_box": loader.recipe_data["bounding_box"], + "composition": {}, + } + if "grid_file_path" in loader.recipe_data: + recipe_meta_data["grid_file_path"] = loader.recipe_data["grid_file_path"] + return recipe_meta_data + except KeyError as e: + sys.exit(f"Recipe metadata is missing. {e}") + + def upload( recipe_path, db_id=DATABASE_IDS.FIREBASE, @@ -23,7 +42,7 @@ def upload( if FirebaseHandler._initialized: recipe_loader = RecipeLoader(recipe_path) recipe_full_data = recipe_loader._read(resolve_inheritance=False) - recipe_meta_data = recipe_loader.get_only_recipe_metadata() + recipe_meta_data = get_recipe_metadata(recipe_loader) recipe_db_handler = DBUploader(db_handler) recipe_db_handler.upload_recipe(recipe_meta_data, recipe_full_data) else: