Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 62 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@

An algorithm to pack molecular recipes

**Try cellPACK online:** [cellpack.allencell.org](https://cellpack.allencell.org)

## Installation

> [!NOTE]
> These are the basic installation steps. However, our recommendation for developers is to install using `uv`. See advanced installation instructions [here](./docs/INSTALL.md).
> These are the basic installation steps. However, our recommendation for developers is to install using `uv`. See advanced installation instructions [here](./docs/INSTALLATION.md).

1. Install Python 3.11 and `git`. Update pip at least to `24.0.0`.
2. Clone this git repository.
Expand All @@ -30,9 +32,65 @@ pip install -e .
```

## Pack example recipes
1. v1: `pack -r examples/recipes/v1/NM_Analysis_FigureB1.0.json`
2. v2: `pack -r examples/recipes/v2/spheres_in_a_box.json`
3. Pack from remote server: `pack -r github:recipes/NM_Analysis_FigureB1.0.json `

cellPACK supports two recipe formats: **v1** (legacy) from the original publication, and **v2** (modern) with improved structure. We recommend starting with **v2** for new recipes.

### Recipe Format Versions

#### v1 Recipes (Legacy Format)
**v1 recipes** use the original schema from the [Nature Methods publication](https://www.nature.com/articles/nmeth.3204). These recipes feature:
- Explicit parameter definitions for all ingredients
- Backward compatibility with the original cellPACK publication examples

**Example v1 recipes:**
- `NM_Analysis_FigureB1.0.json` - Blood plasma mesoscale model from the Nature Methods publication
- `BloodPlasma_noHIV_1.0_2D.json` - 2D blood plasma model
- `partner_packing.json` - Example of molecular partner binding

**Run a v1 recipe:**
```bash
pack -r examples/recipes/v1/NM_Analysis_FigureB1.0.json
```

![Blood Plasma Model Result](docs/images/nm_analysis_figure_b1_res.png)

#### v2 Recipes (Modern Format)
**v2 recipes** use a modernized schema with improved structure and features:
- Cleaner organization with `objects` and `composition` sections
- Object inheritance system for efficient recipe authoring
- Better support for complex cellular environments

**Example v2 recipes:**
- `spheres_in_a_box.json` - Simple 3D multi-sphere packing (great for getting started)
- `peroxisome.json` - Peroxisome organelle model
- `er_peroxisome.json` - Endoplasmic reticulum with peroxisomes
- `vector_gradient.json` - Demonstrates gradient-based ingredient distributions
- `partner_packing.json` - Molecular partner interactions

**Run a v2 recipe:**
```bash
pack -r examples/recipes/v2/spheres_in_a_box.json
```

![Multi-Sphere Result](docs/images/spheres_in_a_box_res.png)

### Remote Recipe Loading
You can also load recipes directly from remote servers:
```bash
pack -r github:recipes/NM_Analysis_FigureB1.0.json
```

### Config Files
Config files control packing behavior and simulation parameters including:
- **Place methods** - Algorithm used for ingredient placement (e.g., `jitter`, `spheresSST`)
- **Output formats** - Save options for results and analysis
- **Grid settings** - Spatial grid parameters for collision detection
- **Debugging options** - Visualization and diagnostic tools

**Using a config file:**
```bash
pack -r examples/recipes/v2/spheres_in_a_box.json -c examples/packing-configs/debug.json
```

**Stable Release:** `pip install cellpack`<br>
**Development Head:** `pip install git+https://github.com/mesoscope/cellpack.git`
Expand Down
2 changes: 1 addition & 1 deletion cellpack/autopack/AWSHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def save_file_and_get_url(self, file_path):
if self.is_url_valid(base_url):
return file_name, base_url
except NoCredentialsError as e:
print(f"AWS credentials are not configured, details:{e}")
logging.warning(f"AWS credentials are not configured: {e}")
return None, None
return None, None

Expand Down
2 changes: 2 additions & 0 deletions cellpack/autopack/DBRecipeHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,8 @@ def compile_db_recipe_data(db_recipe_data, obj_dict, grad_dict, comp_dict):
}
if db_recipe_data.get("grid_file_path"):
recipe_data["grid_file_path"] = db_recipe_data.get("grid_file_path")
if db_recipe_data.get("randomness_seed"):
recipe_data["randomness_seed"] = db_recipe_data.get("randomness_seed")
if grad_dict:
recipe_data["gradients"] = [
{**v} for v in DBRecipeLoader.remove_dedup_hash(grad_dict).values()
Expand Down
4 changes: 4 additions & 0 deletions cellpack/autopack/FirebaseHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ def which_db(default_db=None):
if default_db in options.values():
log.debug(f"Using {default_db} database -------------")
return default_db
# detect if running in a non-interactive environment(CI, Docker, etc), default to staging db
if not os.isatty(0):
log.debug("Non-interactive environment detected, using staging database")
return "staging"
choice = input(
f"Enter number for database ({', '.join([f'{k}: {v}' for k, v in options.items()])}): "
).strip()
Expand Down
3 changes: 2 additions & 1 deletion cellpack/autopack/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ def checkPath():
"autopackdata": appdata,
f"{DATABASE_IDS.GITHUB.value}:": autoPACKserver,
f"{DATABASE_IDS.FIREBASE.value}:": None,
f"{DATABASE_IDS.AWS.value}:": None,
}


Expand Down Expand Up @@ -400,7 +401,7 @@ def load_file(
if not initialize_db._initialized:
readme_url = "https://github.com/mesoscope/cellpack?tab=readme-ov-file#introduction-to-remote-databases"
sys.exit(
f"The selected database: {database_name} is not initialized. Please set up credentials to pack remote recipes. Refer to the instructions at {readme_url}"
f"The selected database: {database_name} is not initialized. Please set up credentials to pack remote recipes. Refer to the instructions at {readme_url}, or try cellPACK web interface: https://cellpack.allencell.org (no setup required)"
)
db_handler = DBRecipeLoader(initialize_db)
db_handler.validate_input_recipe_path(filename)
Expand Down
4 changes: 3 additions & 1 deletion cellpack/autopack/interface_objects/database_ids.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ def with_colon(cls):

@classmethod
def handlers(cls):
def create_aws_handler(bucket_name, sub_folder_name, region_name):
def create_aws_handler(
bucket_name=None, sub_folder_name=None, region_name=None
):
return AWSHandler(
bucket_name=bucket_name,
sub_folder_name=sub_folder_name,
Expand Down
4 changes: 2 additions & 2 deletions cellpack/autopack/loaders/config_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class ConfigLoader(object):
"ordered_packing": False,
"out": "out/",
"overwrite_place_method": False,
"open_results_in_browser": True,
"open_results_in_browser": False,
"parallel": False,
"place_method": "spheresSST",
"randomness_seed": None,
Expand All @@ -47,7 +47,7 @@ class ConfigLoader(object):
"show_sphere_trees": False,
"show_progress_bar": True,
"spacing": None,
"upload_results": True,
"upload_results": False,
"use_periodicity": False,
"version": 1.0,
}
Expand Down
11 changes: 6 additions & 5 deletions cellpack/autopack/upy/simularium/simularium_helper.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
# standardmodule
import logging
import os
import webbrowser
from pathlib import Path
Expand Down Expand Up @@ -1379,7 +1380,7 @@ def raycast(self, **kw):
def raycast_test(self, obj, start, end, length, **kw):
return

def post_and_open_file(self, file_name, open_results_in_browser=True):
def post_and_open_file(self, file_name, open_results_in_browser):
simularium_file = Path(f"{file_name}.simularium")
url = None
job_id = os.environ.get("AWS_BATCH_JOB_ID", None)
Expand Down Expand Up @@ -1414,8 +1415,8 @@ def store_result_file(file_path, storage=None, batch_job_id=None):
file_name, url = initialized_handler.save_file_and_get_url(file_path)
if not file_name or not url:
db_maintainer = DBMaintenance(initialized_handler)
print(
f"If AWS access needed, please refer to the instructions at {db_maintainer.readme_url()}. \nSkipping the opening of new browser tabs -------------"
logging.warning(
f"Skipping browser opening, upload credentials not configured. For setup instructions see: {db_maintainer.readme_url()}"
)
return file_name, url

Expand All @@ -1431,8 +1432,8 @@ def store_metadata(file_name, url, db=None, job_id=None):
db_uploader.upload_result_metadata(file_name, url, job_id)
else:
db_maintainer = DBMaintenance(initialized_db)
print(
f"Firebase credentials are not found. If needed, please refer to the instructions at {db_maintainer.readme_url()}. \nSkipping firebase staging database -------------"
logging.warning(
f"Firebase credentials not found. For setup instructions see: {db_maintainer.readme_url()}. Or try cellPACK web interface: https://cellpack.allencell.org (no setup required)"
)
return

Expand Down
14 changes: 0 additions & 14 deletions cellpack/autopack/validation/recipe_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,20 +479,6 @@ def validate_gradient_surface_objects(self):
)
return self

@model_validator(mode="after")
def validate_gradient_combinations(self):
"""Validate gradient combinations in object gradient lists"""
if hasattr(self, "objects") and self.objects:
for obj_name, obj_data in self.objects.items():
if hasattr(obj_data, "gradient") and obj_data.gradient is not None:
if isinstance(obj_data.gradient, list):
# multiple gradients - validate combination
if len(obj_data.gradient) < 2:
raise ValueError(
f"objects.{obj_name}.gradient: gradient lists must contain at least 2 gradients"
)
return self

@model_validator(mode="after")
def validate_object_inheritance(self):
"""Validate that object inherit references point to existing objects in the objects section"""
Expand Down
4 changes: 2 additions & 2 deletions cellpack/autopack/writers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,8 @@ def save_as_simularium(self, env, seed_to_results_map):
result_file_name, env.boundingBox, env.name, env.version
)
number_of_packings = env.config_data.get("number_of_packings", 1)
open_results_in_browser = env.config_data.get("open_results_in_browser", True)
upload_results = env.config_data.get("upload_results", True)
open_results_in_browser = env.config_data.get("open_results_in_browser", False)
upload_results = env.config_data.get("upload_results", False)
if (number_of_packings == 1 or is_aggregate) and upload_results:
autopack.helper.post_and_open_file(file_name, open_results_in_browser)

Expand Down
2 changes: 2 additions & 0 deletions cellpack/bin/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ def get_recipe_metadata(loader):
}
if "grid_file_path" in loader.recipe_data:
recipe_meta_data["grid_file_path"] = loader.recipe_data["grid_file_path"]
if "randomness_seed" in loader.recipe_data:
recipe_meta_data["randomness_seed"] = loader.recipe_data["randomness_seed"]
return recipe_meta_data
except KeyError as e:
sys.exit(f"Recipe metadata is missing. {e}")
Expand Down
4 changes: 2 additions & 2 deletions docs/CONFIG_SCHEMA.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The config file controls the packing behavior. It specifies parameters such as p
| `load_from_grid_file` | boolean | Load objects from a grid file | False | |
| `name` | string | Name of the config | default | Used to identify this config run |
| `number_of_packings` | number (>=1) | Number of independent packing replicates | 1 | |
| `open_results_in_browser` | boolean | Open results in browser after run | True | |
| `open_results_in_browser` | boolean | Open results in browser after run | False | Prerequisite: AWS s3 credentials |
| `ordered_packing` | boolean | Use deterministic packing order | False | |
| `out` | string | Output directory path | `"out/"` | |
| `overwrite_place_method` | boolean | Override object-specific place methods | False | |
Expand All @@ -26,7 +26,7 @@ The config file controls the packing behavior. It specifies parameters such as p
| `show_progress_bar` | boolean | Show progress bar in terminal | False | |
| `show_sphere_trees` | boolean | Visualize sphere trees | False | |
| `spacing` | number | Override object spacing | None | |
| `upload_results` | boolean | Upload results to S3 | True | |
| `upload_results` | boolean | Upload results to S3 | False | Requires AWS S3 credentials to upload the result file to S3 | |
| `use_periodicity` | boolean | Enable periodic boundary conditions | False | |
| `version` | number | Config version number | 1.0 | For internal tracking |
| `image_export_options.hollow` | boolean | Export hollow images | False | |
Expand Down
4 changes: 2 additions & 2 deletions docs/INSTALLATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ cd /path/to/directory/
**2. Clone the repo from GitHub**

```bash
git clone git@github.com:mesoscope/cellpack-analysis.git
cd cellpack-analysis
git clone git@github.com:mesoscope/cellpack.git
cd cellpack
```

**3. Install the dependencies using uv**
Expand Down
Binary file added docs/images/nm_analysis_figure_b1_res.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/spheres_in_a_box_res.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ CONTRIBUTING
```

```{include} ../README.md
:relative-docs: ./docs/
:relative-docs: docs/
:relative-images:
```

- {ref}`genindex`
Expand Down
6 changes: 6 additions & 0 deletions examples/packing-configs/upload_and_open_result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "upload_results_and_open_in_browser",
"upload_results": true,
"open_results_in_browser": true,
"save_analyze_result": true
}
14 changes: 7 additions & 7 deletions examples/recipes/v2/one_sphere.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
"name": "one_sphere",
"bounding_box": [
[
0,
0,
0
-20,
-20,
-20
],
[
20,
20,
20
100,
100,
100
]
],
"objects": {
Expand Down Expand Up @@ -58,7 +58,7 @@
0.5,
0.5
],
"radius": 5,
"radius": 40,
"max_jitter": [
1,
1,
Expand Down
2 changes: 1 addition & 1 deletion examples/recipes/v2/spheres_in_a_box.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
[
1000,
1000,
1000
1500
]
],
"objects": {
Expand Down