Skip to content

validate recipes during load#402

Merged
rugeli merged 6 commits intomainfrom
feature/consolidate-validation
Oct 10, 2025
Merged

validate recipes during load#402
rugeli merged 6 commits intomainfrom
feature/consolidate-validation

Conversation

@rugeli
Copy link
Copy Markdown
Collaborator

@rugeli rugeli commented Oct 2, 2025

Problem

closes #401

Solution

  • move validation to RecipeLoader._read() after data migration
    • fixed validation error when packing v1 recipes
    • consolidated validation to one spot that works for all recipes (v1/v2/firebase)
  • Simplify validate.py to use RecipeLoader for all recipe
  • improved data migration tests for orientBiasRotRange

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Refactor (non-breaking change which adds functionality)

Steps to Verify:

  1. run validate [ANY-VALID-RECIPE-PATH]
    • v1 validate examples/recipes/v1/one_sphere.json
    • v2 validate examples/recipes/v2/pcna_surface_gradient.json
    • firebase validate firebase:recipes/gradients_v_default -d
  2. run pack -r [ANY-VALID-RECIPE-PATH]

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Oct 2, 2025

Packing analysis report

Analysis for packing results located at cellpack/tests/outputs/test_spheres/spheresSST

Ingredient name Encapsulating radius Average number packed
ext_A 25 236.0

Packing image

Packing image

Distance analysis

Expected minimum distance: 50.00
Actual minimum distance: 50.01

Ingredient key Pairwise distance distribution
ext_A Distance distribution ext_A

@rugeli rugeli force-pushed the feature/consolidate-validation branch from d894a7c to a9cda3b Compare October 2, 2025 22:55
@rugeli rugeli requested a review from ascibisz October 2, 2025 23:28
Copy link
Copy Markdown
Collaborator

@ascibisz ascibisz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like the code change moving the validation to recipe_loader! I tested it out and it works great.

I don't fully understand the context of the changes in migrate_v1_to_v2, but the code looks good and is very readable. But just wanted to call out that blindspot I have, I don't know much about migrate_v1_to_v2 and if you have concerns about that code change, I would suggest tagging another reviewer who has more context.

else:
range_min = -pi
range_max = pi

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed a bug in the conversion function to prevent invalid ranges where min>max (e.g. [6, pi])

},
"B": {
"orient_bias_range": [6, pi],
"orient_bias_range": [-pi, 6],
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated test data for orient_bias_range accordingly

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why the test_single_spheres recipe has these values for the rotation bias range.

A thought: all angles should be converted to be within the range [-pi, pi] before any subsequent comparisons. [6,12] doesn't really make any geometric sense.

This should also make the convert_rotation_range easier to implement. Something like

def constrain_angle(angle):
    return (angle + np.pi) % (2 * np.pi) - np.pi

could help

@rugeli rugeli requested a review from mogres October 6, 2025 22:34
Copy link
Copy Markdown
Collaborator

@mogres mogres left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love the recipe validation during read time! I have some comments about the orientation bias range conversion, but the validation updates look good to me!

if "orientBiasRotRangeMax" in old_ingredient
else pi
)
has_min = "orientBiasRotRangeMin" in old_ingredient
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic flow is a bit confusing. Are there any example recipes where the min range is greater than the max range which requires doing this correction?


import cellpack.autopack as autopack

log = logging.getLogger(__name__)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line can go after the imports

# validate recipe after migration to v2.1 format but before transforming to class instances
try:
RecipeValidator.validate_recipe(recipe_data)
log.info("Recipe validation passed")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this should be a debug statement instead of info?


RecipeValidator.validate_recipe(raw_recipe_data)
log.info(f"Local recipe {raw_recipe_data['name']} is valid!")
use_docker = recipe_path.startswith("firebase:")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this always true? What about users packing firebase recipes locally? Maybe the variable name in RecipeLoader could be updated to cover these use cases?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point! I agree the name use_docker is a bit confusing here, and we can totally replace the hardcoded "firebase" with DATABSE_IDS. I'll make a overall refinement!

use_docker = recipe_path.startswith("firebase:")
loader = RecipeLoader(recipe_path, use_docker=use_docker)
recipe_data = loader.recipe_data
log.info(f"Recipe {recipe_data['name']} is valid!")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably be a debug instead of info.

},
"B": {
"orient_bias_range": [6, pi],
"orient_bias_range": [-pi, 6],
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why the test_single_spheres recipe has these values for the rotation bias range.

A thought: all angles should be converted to be within the range [-pi, pi] before any subsequent comparisons. [6,12] doesn't really make any geometric sense.

This should also make the convert_rotation_range easier to implement. Something like

def constrain_angle(angle):
    return (angle + np.pi) % (2 * np.pi) - np.pi

could help

rugeli and others added 4 commits October 8, 2025 09:19
* fix v1-v2 orient bias range migration tests

* Update cellpack/autopack/loaders/migrate_v1_to_v2.py

Co-authored-by: Saurabh Mogre <saurabh.mogre@alleninstitute.org>

* Update cellpack/autopack/loaders/migrate_v1_to_v2.py

Co-authored-by: Saurabh Mogre <saurabh.mogre@alleninstitute.org>

* Update cellpack/tests/test_recipe_version_migration.py

Co-authored-by: Saurabh Mogre <saurabh.mogre@alleninstitute.org>

* Update cellpack/tests/test_recipe_version_migration.py

Co-authored-by: Saurabh Mogre <saurabh.mogre@alleninstitute.org>

* Update cellpack/tests/test_recipe_version_migration.py

Co-authored-by: Saurabh Mogre <saurabh.mogre@alleninstitute.org>

* Update cellpack/tests/test_recipe_version_migration.py

Co-authored-by: Saurabh Mogre <saurabh.mogre@alleninstitute.org>

* Update cellpack/tests/test_recipe_version_migration.py

Co-authored-by: Saurabh Mogre <saurabh.mogre@alleninstitute.org>

* Update cellpack/tests/test_recipe_version_migration.py

Co-authored-by: Saurabh Mogre <saurabh.mogre@alleninstitute.org>

* Update cellpack/tests/test_recipe_version_migration.py

Co-authored-by: Saurabh Mogre <saurabh.mogre@alleninstitute.org>

* Update cellpack/tests/test_recipe_version_migration.py

Co-authored-by: Saurabh Mogre <saurabh.mogre@alleninstitute.org>

* Update cellpack/tests/test_recipe_version_migration.py

Co-authored-by: Saurabh Mogre <saurabh.mogre@alleninstitute.org>

* Update cellpack/tests/test_recipe_version_migration.py

Co-authored-by: Saurabh Mogre <saurabh.mogre@alleninstitute.org>

* Fix indent

* update validation

* remove range swap

* fix compartment test

---------

Co-authored-by: Saurabh Mogre <saurabh.mogre@alleninstitute.org>
@rugeli rugeli merged commit 567eecc into main Oct 10, 2025
7 checks passed
@rugeli rugeli deleted the feature/consolidate-validation branch October 10, 2025 21:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Validate v1/v2/remote recipe data in recipe_loader

3 participants