pen-stack 6.5.0__tar.gz → 6.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pen_stack-6.5.0 → pen_stack-6.7.0}/CHANGELOG.md +65 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/CITATION.cff +2 -2
- {pen_stack-6.5.0 → pen_stack-6.7.0}/PKG-INFO +28 -14
- {pen_stack-6.5.0 → pen_stack-6.7.0}/README.md +27 -13
- pen_stack-6.7.0/benchmarks/position_effect/README.md +60 -0
- pen_stack-6.7.0/benchmarks/position_effect/SHA256SUMS +1 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/genotoxicity_oracle.yaml +19 -19
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/metric_guide.yaml +1 -1
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/oracles/scope_cards.yaml +4 -4
- pen_stack-6.7.0/docs/cards/position_effect_data.md +36 -0
- pen_stack-6.7.0/docs/position_effect.md +57 -0
- pen_stack-6.7.0/docs/tpe_bench.md +48 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/__init__.py +1 -1
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/data/ingest_safety_annot.py +48 -11
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/genotoxicity_oracle.py +6 -6
- pen_stack-6.7.0/pen_stack/twin/data/__init__.py +12 -0
- pen_stack-6.7.0/pen_stack/twin/data/position_effect.py +224 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/twin/outcome.py +23 -5
- pen_stack-6.7.0/pen_stack/twin/position_effect.py +368 -0
- pen_stack-6.7.0/pen_stack/validate/expr_controls.py +39 -0
- pen_stack-6.7.0/pen_stack/validate/heldout_celltype_expr.py +32 -0
- pen_stack-6.7.0/pen_stack/validate/known_biology_expr.py +38 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack.egg-info/PKG-INFO +28 -14
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack.egg-info/SOURCES.txt +15 -0
- pen_stack-6.7.0/prereg/SHA256_LOCK_ws_expr2.json +8 -0
- pen_stack-6.7.0/prereg/ws_expr2.yaml +39 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pyproject.toml +1 -1
- pen_stack-6.7.0/scripts/fetch_licensed_sources.py +57 -0
- pen_stack-6.7.0/scripts/p1_build_position_effect.py +103 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/scripts/p52_build_genotox_oracle.py +7 -4
- {pen_stack-6.5.0 → pen_stack-6.7.0}/LICENSE +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/MANIFEST.in +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/bench/run.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/benchmarks/genome_writing_bench/LEADERBOARD.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/benchmarks/genome_writing_bench/README.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/benchmarks/genome_writing_bench/SHA256SUMS +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/benchmarks/genome_writing_bench/SUBMISSIONS.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/benchmarks/genome_writing_bench/tasks.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/benchmarks/genome_writing_challenge/README.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/benchmarks/genome_writing_challenge/SUBMISSIONS.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/antipeg.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/atlas_families.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/bridge_offtarget_profile.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/calibration/preexisting_nab_independent.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/capsid_epitope_oracle.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/capsid_sequences.fasta +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/cargo_polish.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/cell_types.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/datasets.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/delivery_constraints.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/delivery_rules.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/delivery_vehicles.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/expression/modifiers.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/expression/promoters.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/gates_v3.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/gsh_validated_heldout.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/intent_weights.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/known_unknowns.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/llm.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/monitor_queries.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/oracles/execution.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/rules/delivery.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/rules/fold.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/rules/multiplex.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/rules/payload.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/rules/reachability.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/safety/hazard_registry.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/safety/policy.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/safety/probes.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/score_axes.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/seroprevalence.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/target_sites.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/universe_crosswalk.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/write_types.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/configs/wtkb_curated.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/data/curated/bridge_offtarget_energetics.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/data/curated/bridge_offtarget_profile_measured.parquet +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/data/curated/gene_coords.parquet +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/data/curated/unified_editor_universe.parquet +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/BACKLOG.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/DEPLOY.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/INFRA.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/MCP.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/RELEASING.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/REPRO.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/STABILITY.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/agent.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/alphagenome_feasibility.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/autonomy.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/benchmark_circularity.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/biosecurity.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/build_interface.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/cards/atlas.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/cards/durability.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/cards/safety.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/challenge.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/closed_loop.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/co_scientist.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/co_scientist_loop.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/delivery.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/delivery_immunology.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/digital_twin.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/dissemination.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/environment.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/experiment_design.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/generative_design.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/index.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/integrations.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/live_oracles.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/mechanistic_constraints.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/oracles.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/positioning.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/private_data_formats.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/quickstart.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/responsible_use.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/rules.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/scope.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/scorecard.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/tutorials/compare-families.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/tutorials/score-deliverability.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/tutorials/where-can-i-write.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/tutorials/which-writer-reaches-locus.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/uncertainty.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/verify.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/world_model.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/writer_verification.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/docs/wtkb.md +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/_resources.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/active/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/active/acquire.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/active/design.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/active/validate.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/adapt/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/adapt/finetune.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/adapt/ingest.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/adapt/pipeline.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/adapt/recalibrate.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/adapt/report.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/agent/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/agent/cite.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/agent/co_scientist.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/agent/epistemic.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/agent/guardrails.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/agent/mcp_server.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/agent/orchestrator.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/agent/orchestrator_live.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/agent/pen_agent.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/agent/scope.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/agent/tools.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/api/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/api/manifest.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/atlas/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/atlas/build_wtkb.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/atlas/crosslink.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/atlas/expand.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/atlas/schema.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/atlas/scorecard.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/atlas/universe.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/atlas/variant_propose.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/atlas/writer_verify.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/bridge/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/bridge/activity.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/bridge/cli.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/bridge/fold_qc.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/bridge/guide_qc.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/bridge/ingest.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/bridge/offtarget.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/bridge/offtarget_energetics.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/bridge/ortholog_screen.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/bridge/pipeline.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/build/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/build/ingest.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/build/protocol.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/build/simlab.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/cli.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/data/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/data/encode.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/data/genome.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/data/ingest_chromatin.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/data/ingest_integration.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/data/ingest_trip.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/design/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/design/generate.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/design/pareto.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/design/space.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/env/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/env/genome_writing_env.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/env/policies.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/graph/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/graph/build.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/graph/cell_types.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/graph/ingest.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/graph/query.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/graph/schema.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/loop/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/loop/continual.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/loop/cycle.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/loop/drift.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/mech/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/mech/classify_atlas.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/mech/whitelist.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/monitor/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/monitor/europepmc.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/monitor/run.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/monitor/triage.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/oracles/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/oracles/cache.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/oracles/energetics.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/oracles/genome.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/oracles/protein_design.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/oracles/rna.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/oracles/schema.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/oracles/status.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/oracles/structure.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/oracles/vcell.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/antipeg_oracle.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/capsid_epitope_oracle.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/cargo.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/cargo_polish.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/delivery.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/delivery_constraints.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/delivery_immunology.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/delivery_vehicles.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/immune_profile.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/innate_sensing.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/multiplex.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/optimize.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/pipeline.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/report.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/router.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/seroprevalence_oracle.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/planner/target_site.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/rag/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/rag/index.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/rag/llm.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/rag/qa.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/rules/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/rules/evaluators.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/rules/loader.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/rules/schema.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/rules/solver.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/safety/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/safety/audit.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/safety/gate.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/safety/policy.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/safety/redteam.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/safety/registry.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/safety/screen.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/score/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/score/recalibrate.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/score/therapeutic.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/server/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/server/api.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/twin/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/twin/calibrate.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/twin/mechanistic.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/ui/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/ui/app.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/adapt_demo.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/agent_eval.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/bench_adversarial_tasks.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/bench_coscientist_tasks.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/bench_graph_tasks.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/bench_rule_tasks.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/bench_trust_tasks.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/bench_writetype_tasks.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/blind_gsh_discovery.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/cargo_directionality.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/closed_loop.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/durability_baselines.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/experiment_design.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/forward_hypotheses.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/generative_design.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/guide_qc_demo.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/immune_calibration.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/intent_specification.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/offtarget_energetics_eval.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/out_of_scope_refusal.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/outcome_calibration.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/outcome_prediction.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/paper3_benchmark.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/paper4_real_validation.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/paper4_validation.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/protocol_safety.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/safety_screening.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/selective_prediction.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/seq_vs_measured.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/target_site_controls.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/uncertainty_eval.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/ungrounded_baseline.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/within_locus_ranking.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/validate/writer_recovery.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/verify/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/verify/schema.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/verify/service.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/web/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/web/guide.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/web/llm.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/web/router.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/web/server.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/web/tools.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/wgenome/__init__.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/wgenome/chromatin_seq.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/wgenome/durability.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/wgenome/export_tracks.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/wgenome/features.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/wgenome/gsh_baseline.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/wgenome/mesh_features.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/wgenome/ood.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/wgenome/providers.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/wgenome/safety.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/wgenome/structure3d.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/wgenome/uncertainty.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack/wgenome/writability.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack.egg-info/dependency_links.txt +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack.egg-info/entry_points.txt +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack.egg-info/requires.txt +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/pen_stack.egg-info/top_level.txt +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_phase0.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_phase1_5.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_phase2.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_phase3.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_a.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_acq.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_aldesign.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_alvalidate.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_atlas.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_b.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_ba.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_ba_v33.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_ba_v45.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_bench.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_c.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_cal.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_calib.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_challenge.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_chat.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_cite.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_continual.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_cosci2.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_crit.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_ct.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_d.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_drift.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_e.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_env.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_ep.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_epitope.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_f.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_frontend.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_g.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_gen.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_genotox.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_graph.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_h.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_hybrid.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_immune.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_ingest.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_innate.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_loop.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_manifest.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_mc.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_mcp.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_mech.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_mon.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_o.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_openapi.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_orch.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_outcome.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_pareto.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_peg.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_plan.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_policy.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_profile.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_proto.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_r.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_redteam.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_route.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_screen.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_seroprev.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_simlab.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_twincal.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_uq.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_v.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_vcell.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/SHA256_LOCK_ws_wv.json +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/paper1.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/paper2.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/paper3.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/paper4.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/phase0.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_a.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_acq.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_aldesign.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_alvalidate.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_atlas.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_b.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_ba.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_ba_v33.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_ba_v45.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_bench.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_c.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_cal.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_calib.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_challenge.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_chat.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_cite.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_continual.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_cosci2.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_crit.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_ct.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_d.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_drift.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_e.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_env.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_ep.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_epitope.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_f.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_frontend.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_g.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_gen.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_genotox.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_graph.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_h.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_hybrid.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_immune.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_ingest.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_innate.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_loop.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_manifest.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_mc.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_mcp.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_mech.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_mon.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_o.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_openapi.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_orch.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_outcome.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_pareto.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_peg.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_plan.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_policy.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_profile.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_proto.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_r.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_redteam.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_route.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_screen.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_seroprev.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_simlab.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_twincal.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_uq.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_v.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_vcell.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/prereg/ws_wv.yaml +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/scripts/calibrate_immune_axes.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/scripts/p1_build_atlas.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/scripts/p1_build_durability.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/scripts/p1_export_tracks.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/scripts/p1_safety_concordance.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/scripts/p1_train_safety.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/scripts/p1_validation_report.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/scripts/p2_build_atlas.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/scripts/p3_benchmark_report.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/scripts/p4_genome_scan.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/scripts/p53_build_epitope_oracle.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/scripts/ws_b_report.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/scripts/ws_c_report.py +0 -0
- {pen_stack-6.5.0 → pen_stack-6.7.0}/setup.cfg +0 -0
|
@@ -3,6 +3,71 @@
|
|
|
3
3
|
All notable changes to PEN-STACK are documented here. This file follows
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/) and the program's phase structure.
|
|
5
5
|
|
|
6
|
+
## [6.7.0] - 2026-06-19 - PEN-EXPRESS: learned, trained-conformal Stage H + TPE-Bench
|
|
7
|
+
|
|
8
|
+
**MINOR feature release.** Upgrades the digital twin's Stage H expression/outcome layer from a validation-failing
|
|
9
|
+
closed-form **heuristic** to a **learned, trained-conformal, decomposable** position-effect model — and ships the
|
|
10
|
+
held-out benchmark the expression capability never had. Wrap, don't rebuild: extends `twin` + `wgenome.uncertainty`
|
|
11
|
+
+ `wgenome.ood` + `benchmarks`. No fabrication: every metric is from a real CV run on real TRIP supervision, and
|
|
12
|
+
the cross-cell-type transfer claim is **data-gated**, never faked.
|
|
13
|
+
|
|
14
|
+
### Added — the learned model + trained conformal (WS-EXPRESS2: WS-D/M/U)
|
|
15
|
+
- `pen_stack/twin/data/position_effect.py` — unified position-effect schema + dataset registry with **verified
|
|
16
|
+
accessions/DOIs** (TRIP live; PatchMPRA/MPIRE/lentiMPRA/Leemans registered + honestly `available=False` until
|
|
17
|
+
fetched), z-normalization within (dataset × cassette), domain-blocked + held-out-cell-type splits + leakage check.
|
|
18
|
+
- `pen_stack/twin/position_effect.py` — `PositionEffectModel` (factored `f_cassette` + `g_context`, LightGBM),
|
|
19
|
+
`evaluate()` (chromosome-blocked CV vs the v3.x durability head + cassette-only, paired-bootstrap CIs,
|
|
20
|
+
separability), split-conformal calibration (`ConformalRegressor`, chromosome-Mondrian, OOD-widened),
|
|
21
|
+
`predict_stage_h()` serving seam. **Result (real TRIP):** expression ρ **0.428 → 0.469** (CI excludes 0);
|
|
22
|
+
held-out conformal coverage **0.885** vs 0.90 nominal.
|
|
23
|
+
- `configs/twin/position_effect_conformal.json` — the shipped calibration (qhat + N + held-out coverage).
|
|
24
|
+
- `scripts/p1_build_position_effect.py` — regenerates the model + conformal artifacts (real CV report).
|
|
25
|
+
|
|
26
|
+
### Changed — Stage H integration (WS-I)
|
|
27
|
+
- `pen_stack/twin/outcome.py` — when a chromatin context is supplied and the artifact is present, `predict_outcome`
|
|
28
|
+
serves the **learned trained-conformal** interval + `p_silenced` + OOD tier (`position_effect` block,
|
|
29
|
+
`stage_h_mode`); with no context/artifact it falls back to the heuristic band — **backward compatible** (the
|
|
30
|
+
v5.9 relative-scale contract is intact).
|
|
31
|
+
|
|
32
|
+
### Added — TPE-Bench + controls (WS-B / WS-V)
|
|
33
|
+
- `benchmarks/position_effect/` — TPE-Bench: a **sealed, SHA-locked** held-out-chromosome track + baseline
|
|
34
|
+
leaderboard (cassette-only / durability head / PEN-EXPRESS factored), submission harness. Leave-one-cell-type-out
|
|
35
|
+
transfer track scaffolded + **data-gated** (no fabricated transfer number).
|
|
36
|
+
- `pen_stack/validate/{expr_controls,known_biology_expr,heldout_celltype_expr}.py` — label-shuffle→chance control,
|
|
37
|
+
H3K9me3-heterochromatin→silencing recovery, the data-gated transfer harness.
|
|
38
|
+
- `tests/unit/test_ws_pe.py` — CI-safe (synthetic planted signal); the real-TRIP claim runs on a checkout, skips in CI.
|
|
39
|
+
|
|
40
|
+
### Honesty
|
|
41
|
+
- Public data **cannot** flip expression to ✅ (the v6.5 wall) — v6.7 ships the learned+calibrated upgrade + the
|
|
42
|
+
benchmark + the honest data-gating, not a manufactured checkmark. Cross-cell-type transfer needs the additional
|
|
43
|
+
human datasets (a data-acquisition step), reported as such. Wet-lab validation omitted by scope.
|
|
44
|
+
|
|
45
|
+
## [6.6.0] - 2026-06-16 - License-clean provenance (COSMIC → CancerMine)
|
|
46
|
+
|
|
47
|
+
**MINOR — provenance refactor, no new science, no capability lost.** The shipped artifact now sources the
|
|
48
|
+
oncogene/TSG/driver list from **CancerMine (CC0)** instead of COSMIC Cancer Gene Census (free for academia but
|
|
49
|
+
**no-redistribution**). Copyright protects the *compiled database*, not the *fact* that a gene is an oncogene — so
|
|
50
|
+
sourcing the *list* from a CC0 compilation removes all licensing doubt while keeping the same capability. Prep for
|
|
51
|
+
the BioFirewall release, whose open repo vendors PEN-STACK's hazard data. Workstream WS-LIC + WS-CM + WS-REGEN.
|
|
52
|
+
|
|
53
|
+
### Changed
|
|
54
|
+
- `pen_stack/data/ingest_safety_annot.py` — `load_cancermine()` (CC0) is the **default** oncogene/TSG source
|
|
55
|
+
(HUGO→coords via GENCODE, `--min-citations` precision knob); `load_cosmic()` stays available but **off by
|
|
56
|
+
default** (bring-your-own-license, local enrichment only).
|
|
57
|
+
- `configs/genotoxicity_oracle.yaml` — regenerated from CancerMine; provenance + DOIs updated (CancerMine
|
|
58
|
+
10.1038/s41592-019-0422-y). `safety_{ct}.pkl` + the Writable-Genome atlas regenerated on CancerMine features
|
|
59
|
+
(re-deposited on Zenodo, superseding the COSMIC-derived deposit).
|
|
60
|
+
|
|
61
|
+
### Added
|
|
62
|
+
- **`DATA_LICENSES.md`** — every source × license × redistribution-status × where-used.
|
|
63
|
+
- `tests/unit/test_data_licenses.py` — **CI license gate**: fails if a restricted source (COSMIC/OncoKB) is the
|
|
64
|
+
shipped derived-data source or a raw restricted gene-list is committed; CancerMine is the default.
|
|
65
|
+
- `scripts/fetch_licensed_sources.py` — bring-your-own-license fetcher for COSMIC/OncoKB (local-only, validation).
|
|
66
|
+
|
|
67
|
+
### Honesty
|
|
68
|
+
- Metrics may shift (CancerMine has broader coverage than CGC) — reported, not hidden. The genotoxicity axis is a
|
|
69
|
+
**mechanism-grounded proxy (🟡, not outcome-validated)** before and after; the swap changes only the *source*.
|
|
70
|
+
|
|
6
71
|
## [6.5.0] - 2026-06-15 - Comprehensive expression model + honest proxy-validation pass
|
|
7
72
|
|
|
8
73
|
**MINOR feature release.** Two threads, one principle (no fabrication):
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
cff-version: 1.2.0
|
|
2
2
|
message: "If you use PEN-STACK, please cite it as below."
|
|
3
3
|
title: "PEN-STACK: open infrastructure for genome writing"
|
|
4
|
-
version: 6.
|
|
5
|
-
date-released: 2026-06-
|
|
4
|
+
version: 6.7.0
|
|
5
|
+
date-released: 2026-06-19
|
|
6
6
|
authors:
|
|
7
7
|
- family-names: "Mahaboob Ali"
|
|
8
8
|
given-names: "Anees Ahmed"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pen-stack
|
|
3
|
-
Version: 6.
|
|
3
|
+
Version: 6.7.0
|
|
4
4
|
Summary: Open infrastructure for genome writing: the Writable Genome atlas, the Writer Atlas, and the Write Planner.
|
|
5
5
|
Author-email: Anees Ahmed Mahaboob Ali <ahmedaneesm@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -90,7 +90,7 @@ every design against rule-grounded mechanism, reports calibrated confidence, cit
|
|
|
90
90
|
[](https://codecov.io/gh/ahmedanees-m/pen-stack)
|
|
91
91
|
[](LICENSE)
|
|
92
92
|
[](https://www.python.org/)
|
|
93
|
-
[](CHANGELOG.md)
|
|
94
94
|
[](docs/STABILITY.md)
|
|
95
95
|
[](tests/)
|
|
96
96
|
[](https://github.com/astral-sh/ruff)
|
|
@@ -148,6 +148,32 @@ demonstrated (v5.12) and the benchmark went public (v5.13).
|
|
|
148
148
|
> unknown funnel remains — made legible (scope flags, known-unknowns, honest baselines, no fabrication), not
|
|
149
149
|
> hidden.
|
|
150
150
|
|
|
151
|
+
## What is new in v6.7 — PEN-EXPRESS (a learned, trained-conformal Stage H + TPE-Bench)
|
|
152
|
+
|
|
153
|
+
Stage H's expression/outcome layer was the stack's weakest link: a closed-form **heuristic** that *failed*
|
|
154
|
+
independent validation (ρ=0.12 vs Damdindorj 2014), with an interval the code itself labelled "**NOT a trained
|
|
155
|
+
conformal interval**." v6.7 replaces it — **wrapping, not rebuilding** the digital twin:
|
|
156
|
+
|
|
157
|
+
- **A learned cassette × context position-effect model** (`pen_stack/twin/position_effect.py`) — factored and
|
|
158
|
+
decomposable (`f_cassette` + `g_context`), trained on the **real TRIP supervision** (Akhtar 2013; GEO
|
|
159
|
+
GSE49806/49807). On chromosome-blocked CV it **beats the v3.x durability head** on expression (ρ **0.428 →
|
|
160
|
+
0.469**, paired-bootstrap CI excludes 0) and matches it on silencing — reported honestly, with the separability
|
|
161
|
+
result (additive `f_cassette + g_context` suffices at this N).
|
|
162
|
+
- **Stage H is now trained-conformal.** The model ships a split-conformal calibration (`ConformalRegressor`,
|
|
163
|
+
chromosome-Mondrian, OOD-widened): **held-out coverage 0.885 vs 0.90 nominal** — the named gap, closed. When a
|
|
164
|
+
chromatin context is supplied, `predict_outcome` serves the calibrated interval + `p_silenced` + OOD tier; with
|
|
165
|
+
no context (or no artifact) it falls back to the heuristic — **backward compatible**.
|
|
166
|
+
- **TPE-Bench** (`benchmarks/position_effect/`) — the held-out benchmark the expression capability never had: a
|
|
167
|
+
**sealed, SHA-locked** held-out-chromosome split + a baseline leaderboard (cassette-only / durability head /
|
|
168
|
+
PEN-EXPRESS). A leave-one-**cell-type**-out transfer track is scaffolded and **honestly data-gated** until the
|
|
169
|
+
additional human datasets (PatchMPRA / MPIRE / lentiMPRA / Leemans) are fetched — **no transfer number is
|
|
170
|
+
fabricated**. Controls: label-shuffle → chance; known-biology recovery (H3K9me3 ↑ → silencing ↑).
|
|
171
|
+
|
|
172
|
+
The honest limit (the v6.5 wall, restated): public data alone cannot flip expression to ✅ — that needs measured
|
|
173
|
+
outcome data at a power the literature does not provide. v6.7 ships the learned+calibrated upgrade + the
|
|
174
|
+
benchmark; the green checkmark stays earned, not manufactured. See [docs/position_effect.md](docs/position_effect.md)
|
|
175
|
+
and [docs/tpe_bench.md](docs/tpe_bench.md).
|
|
176
|
+
|
|
151
177
|
## What is new in v6.4 — Live Oracles (the foundation models actually execute)
|
|
152
178
|
|
|
153
179
|
The foundation-model oracles now **run for real**, not just defer: **ViennaRNA** (in-process), **AlphaGenome**
|
|
@@ -976,18 +1002,6 @@ independently verified.
|
|
|
976
1002
|
- **Grounded services** - every quantitative answer comes from a validated tool call (never a language
|
|
977
1003
|
model); the living database never auto-edits the atlas; clinical directives are refused.
|
|
978
1004
|
|
|
979
|
-
## Papers and phases
|
|
980
|
-
|
|
981
|
-
| # | Title | Phase | Status |
|
|
982
|
-
|---|---|---|---|
|
|
983
|
-
| 1 (flagship) | The Writable Genome: a predictive, writer-aware atlas of safe & durable insertion sites | 1 | complete |
|
|
984
|
-
| 2 (platform) | PEN-STACK: unified open infrastructure for non-destructive genome writing | 2 | complete |
|
|
985
|
-
| 3 (capstone) | The Write Planner: end-to-end inverse design of genomic writes | 3 | complete |
|
|
986
|
-
| 4 (beachhead) | Genome-wide off-target prediction for RNA-guided bridge recombinases | 1.5 | complete |
|
|
987
|
-
| M1 (v3.1) | Writable Genome hardened: strong baselines, AlphaGenome sequence + 3D structural-risk axis | v3.1 B,C,D,F | complete |
|
|
988
|
-
| M2 (v3.1) | The Genome-Writing Bench + PEN-Agent: the writing-side benchmark and a grounded agent | v3.1 E | complete |
|
|
989
|
-
| M3 (v3.1) | Multiplex translocation-risk + bridge-RNA guide QC | v3.1 G | complete |
|
|
990
|
-
|
|
991
1005
|
The v3.1 cycle (workstreams A-H) is recorded in `CHANGELOG.md`, `docs/positioning.md`, and the SHA-locked
|
|
992
1006
|
`prereg/ws_*.yaml`; preprint drafts are in `manuscripts/`.
|
|
993
1007
|
|
|
@@ -15,7 +15,7 @@ every design against rule-grounded mechanism, reports calibrated confidence, cit
|
|
|
15
15
|
[](https://codecov.io/gh/ahmedanees-m/pen-stack)
|
|
16
16
|
[](LICENSE)
|
|
17
17
|
[](https://www.python.org/)
|
|
18
|
-
[](CHANGELOG.md)
|
|
19
19
|
[](docs/STABILITY.md)
|
|
20
20
|
[](tests/)
|
|
21
21
|
[](https://github.com/astral-sh/ruff)
|
|
@@ -73,6 +73,32 @@ demonstrated (v5.12) and the benchmark went public (v5.13).
|
|
|
73
73
|
> unknown funnel remains — made legible (scope flags, known-unknowns, honest baselines, no fabrication), not
|
|
74
74
|
> hidden.
|
|
75
75
|
|
|
76
|
+
## What is new in v6.7 — PEN-EXPRESS (a learned, trained-conformal Stage H + TPE-Bench)
|
|
77
|
+
|
|
78
|
+
Stage H's expression/outcome layer was the stack's weakest link: a closed-form **heuristic** that *failed*
|
|
79
|
+
independent validation (ρ=0.12 vs Damdindorj 2014), with an interval the code itself labelled "**NOT a trained
|
|
80
|
+
conformal interval**." v6.7 replaces it — **wrapping, not rebuilding** the digital twin:
|
|
81
|
+
|
|
82
|
+
- **A learned cassette × context position-effect model** (`pen_stack/twin/position_effect.py`) — factored and
|
|
83
|
+
decomposable (`f_cassette` + `g_context`), trained on the **real TRIP supervision** (Akhtar 2013; GEO
|
|
84
|
+
GSE49806/49807). On chromosome-blocked CV it **beats the v3.x durability head** on expression (ρ **0.428 →
|
|
85
|
+
0.469**, paired-bootstrap CI excludes 0) and matches it on silencing — reported honestly, with the separability
|
|
86
|
+
result (additive `f_cassette + g_context` suffices at this N).
|
|
87
|
+
- **Stage H is now trained-conformal.** The model ships a split-conformal calibration (`ConformalRegressor`,
|
|
88
|
+
chromosome-Mondrian, OOD-widened): **held-out coverage 0.885 vs 0.90 nominal** — the named gap, closed. When a
|
|
89
|
+
chromatin context is supplied, `predict_outcome` serves the calibrated interval + `p_silenced` + OOD tier; with
|
|
90
|
+
no context (or no artifact) it falls back to the heuristic — **backward compatible**.
|
|
91
|
+
- **TPE-Bench** (`benchmarks/position_effect/`) — the held-out benchmark the expression capability never had: a
|
|
92
|
+
**sealed, SHA-locked** held-out-chromosome split + a baseline leaderboard (cassette-only / durability head /
|
|
93
|
+
PEN-EXPRESS). A leave-one-**cell-type**-out transfer track is scaffolded and **honestly data-gated** until the
|
|
94
|
+
additional human datasets (PatchMPRA / MPIRE / lentiMPRA / Leemans) are fetched — **no transfer number is
|
|
95
|
+
fabricated**. Controls: label-shuffle → chance; known-biology recovery (H3K9me3 ↑ → silencing ↑).
|
|
96
|
+
|
|
97
|
+
The honest limit (the v6.5 wall, restated): public data alone cannot flip expression to ✅ — that needs measured
|
|
98
|
+
outcome data at a power the literature does not provide. v6.7 ships the learned+calibrated upgrade + the
|
|
99
|
+
benchmark; the green checkmark stays earned, not manufactured. See [docs/position_effect.md](docs/position_effect.md)
|
|
100
|
+
and [docs/tpe_bench.md](docs/tpe_bench.md).
|
|
101
|
+
|
|
76
102
|
## What is new in v6.4 — Live Oracles (the foundation models actually execute)
|
|
77
103
|
|
|
78
104
|
The foundation-model oracles now **run for real**, not just defer: **ViennaRNA** (in-process), **AlphaGenome**
|
|
@@ -901,18 +927,6 @@ independently verified.
|
|
|
901
927
|
- **Grounded services** - every quantitative answer comes from a validated tool call (never a language
|
|
902
928
|
model); the living database never auto-edits the atlas; clinical directives are refused.
|
|
903
929
|
|
|
904
|
-
## Papers and phases
|
|
905
|
-
|
|
906
|
-
| # | Title | Phase | Status |
|
|
907
|
-
|---|---|---|---|
|
|
908
|
-
| 1 (flagship) | The Writable Genome: a predictive, writer-aware atlas of safe & durable insertion sites | 1 | complete |
|
|
909
|
-
| 2 (platform) | PEN-STACK: unified open infrastructure for non-destructive genome writing | 2 | complete |
|
|
910
|
-
| 3 (capstone) | The Write Planner: end-to-end inverse design of genomic writes | 3 | complete |
|
|
911
|
-
| 4 (beachhead) | Genome-wide off-target prediction for RNA-guided bridge recombinases | 1.5 | complete |
|
|
912
|
-
| M1 (v3.1) | Writable Genome hardened: strong baselines, AlphaGenome sequence + 3D structural-risk axis | v3.1 B,C,D,F | complete |
|
|
913
|
-
| M2 (v3.1) | The Genome-Writing Bench + PEN-Agent: the writing-side benchmark and a grounded agent | v3.1 E | complete |
|
|
914
|
-
| M3 (v3.1) | Multiplex translocation-risk + bridge-RNA guide QC | v3.1 G | complete |
|
|
915
|
-
|
|
916
930
|
The v3.1 cycle (workstreams A-H) is recorded in `CHANGELOG.md`, `docs/positioning.md`, and the SHA-locked
|
|
917
931
|
`prereg/ws_*.yaml`; preprint drafts are in `manuscripts/`.
|
|
918
932
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# TPE-Bench — the Position-Effect / Expression track
|
|
2
|
+
|
|
3
|
+
The **expression** capability of PEN-STACK never had a held-out benchmark. TPE-Bench is the position-effect
|
|
4
|
+
track for the [Genome-Writing Challenge](../genome_writing_challenge/) (v6.7 PEN-EXPRESS): given a genomic
|
|
5
|
+
**chromatin context** + **cassette**, predict the **integrated-reporter expression** (and silencing) — scored on
|
|
6
|
+
a **sealed held-out split** whose labels the submitter never sees.
|
|
7
|
+
|
|
8
|
+
## Why
|
|
9
|
+
|
|
10
|
+
Position-effect (where an integrated cassette lands → how strongly/durably it expresses) is the writing-relevant
|
|
11
|
+
quantity no safe-harbour resource predicts. TRIP (Akhtar 2013) supervises it directly. TPE-Bench seals a held-out
|
|
12
|
+
split and anchors a baseline leaderboard, so others can build *to* a calibrated expression predictor.
|
|
13
|
+
|
|
14
|
+
## Tracks
|
|
15
|
+
|
|
16
|
+
| Track | Status | What is held out | Metric |
|
|
17
|
+
|---|---|---|---|
|
|
18
|
+
| `chrom_holdout` | **LIVE** | whole chromosomes (`chr2, chr5, chr14, chrX`), frozen + SHA-locked in `split.json` | Spearman ρ (expression) + AUROC (silenced) |
|
|
19
|
+
| `celltype_holdout` | **DATA-GATED** | leave-one-cell-type-out (the headline transfer track) | — |
|
|
20
|
+
|
|
21
|
+
`celltype_holdout` is the headline cross-cell-type transfer test. With a single available position-effect cell
|
|
22
|
+
type (mESC) it reports `data_gated` **honestly** and activates once PatchMPRA / MPIRE / lentiMPRA / Leemans are
|
|
23
|
+
fetched — **no transfer number is fabricated** until then.
|
|
24
|
+
|
|
25
|
+
## Baseline leaderboard (sealed `chrom_holdout`, n_test = 2257)
|
|
26
|
+
|
|
27
|
+
| Predictor | Expression ρ | Silenced AUROC |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| cassette-only (f_cassette) | 0.178 | — |
|
|
30
|
+
| context-only (v3.x durability head) | 0.431 | 0.660 |
|
|
31
|
+
| **PEN-EXPRESS factored (f_cassette + g_context)** | **0.475** | 0.660 |
|
|
32
|
+
|
|
33
|
+
The factored model's gain is on **expression** (the cassette term lifts ρ 0.431 → 0.475 on the sealed test); the
|
|
34
|
+
silenced classifier matches the durability head (the silencing question is chromatin-driven — reported honestly,
|
|
35
|
+
not inflated). See `../../out/position_effect_report.json` for the full CV report + bootstrap CIs.
|
|
36
|
+
|
|
37
|
+
## How to submit
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from benchmarks.position_effect.harness import Submission, evaluate
|
|
41
|
+
|
|
42
|
+
def my_predict(public_input: dict):
|
|
43
|
+
# public_input = {task_id, family, cassette, chromatin_features:{H3K27ac,...}, instructions}; label hidden
|
|
44
|
+
return {"expression": 0.0, "p_silenced": 0.5} # return your prediction (abstain-safe)
|
|
45
|
+
|
|
46
|
+
print(evaluate(Submission(name="my-model", predict_fn=my_predict)))
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Reference baselines: `python -c "from benchmarks.position_effect.harness import baseline_leaderboard as b; print(b())"`.
|
|
50
|
+
|
|
51
|
+
## Rules
|
|
52
|
+
|
|
53
|
+
- **Sealed + SHA-locked.** `split.json` (held-out chromosomes) is frozen and checksummed (`SHA256SUMS`) before
|
|
54
|
+
model selection — verify with `sha256sum -c SHA256SUMS`.
|
|
55
|
+
- **No circular labels.** The label is the **measured** TRIP expression, never a submitter claim.
|
|
56
|
+
- **Leakage-controlled.** Held out by whole chromosome (nearby integrations share chromatin).
|
|
57
|
+
- **Honest data-gating.** The transfer track abstains until ≥2 cell types exist; no fabricated number.
|
|
58
|
+
- **Deterministic.** PEN-EXPRESS anchors the leaderboard.
|
|
59
|
+
|
|
60
|
+
Data: TRIP (Akhtar et al., *Cell* 2013; GEO GSE49806/GSE49807; trip.nki.nl). License: see `DATA_LICENSES.md`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2fc12cbf28531e68f6e25586da1d84003eeb6a098c9015998ce03f518546bc8a split.json
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
version: '1.0'
|
|
2
|
-
built: '2026-06-
|
|
2
|
+
built: '2026-06-16'
|
|
3
3
|
description: 'computed integration-site genotoxicity oracle: per vector class, the
|
|
4
|
-
observed enrichment of integration sites within window_bp of a
|
|
5
|
-
genome background. genotox_score = min(1, 1/enrichment). In-vivo clonal
|
|
6
|
-
is NOT modelled (stays a known-unknown).'
|
|
4
|
+
observed enrichment of integration sites within window_bp of a CancerMine (CC0)
|
|
5
|
+
oncogene vs genome background. genotox_score = min(1, 1/enrichment). In-vivo clonal
|
|
6
|
+
outcome is NOT modelled (stays a known-unknown).'
|
|
7
7
|
window_bp: 50000
|
|
8
|
-
genome_background_frac_oncogene_50kb: 0.
|
|
8
|
+
genome_background_frac_oncogene_50kb: 0.11538
|
|
9
9
|
inputs:
|
|
10
10
|
visdb: VISDB per-virus hg38 catalogues
|
|
11
|
-
oncogenes:
|
|
11
|
+
oncogenes: CancerMine (CC0) via safety_annot
|
|
12
12
|
provenance_dois:
|
|
13
13
|
- 10.1093/nar/gkz867
|
|
14
|
-
- 10.1038/
|
|
14
|
+
- 10.1038/s41592-019-0422-y
|
|
15
15
|
- 10.1016/S0092-8674(02)00864-4
|
|
16
16
|
- 10.1126/science.1083413
|
|
17
17
|
robust_min_n: 1000
|
|
@@ -19,29 +19,29 @@ classes:
|
|
|
19
19
|
lentiviral:
|
|
20
20
|
virus: HIV
|
|
21
21
|
n_sites: 88743
|
|
22
|
-
frac_oncogene_50kb: 0.
|
|
23
|
-
ci95: 0.
|
|
24
|
-
enrichment:
|
|
22
|
+
frac_oncogene_50kb: 0.2244
|
|
23
|
+
ci95: 0.00274
|
|
24
|
+
enrichment: 1.945
|
|
25
25
|
frac_genotoxic_cis: 0.000293
|
|
26
|
-
median_dist_oncogene:
|
|
26
|
+
median_dist_oncogene: 256384
|
|
27
27
|
robust: true
|
|
28
28
|
deltaretroviral:
|
|
29
29
|
virus: HTLV
|
|
30
30
|
n_sites: 51508
|
|
31
|
-
frac_oncogene_50kb: 0.
|
|
32
|
-
ci95: 0.
|
|
33
|
-
enrichment: 1.
|
|
31
|
+
frac_oncogene_50kb: 0.14472
|
|
32
|
+
ci95: 0.00304
|
|
33
|
+
enrichment: 1.254
|
|
34
34
|
frac_genotoxic_cis: 0.000369
|
|
35
|
-
median_dist_oncogene:
|
|
35
|
+
median_dist_oncogene: 547160
|
|
36
36
|
robust: true
|
|
37
37
|
gammaretroviral:
|
|
38
38
|
virus: MLV
|
|
39
39
|
n_sites: 32
|
|
40
|
-
frac_oncogene_50kb: 0.
|
|
41
|
-
ci95: 0.
|
|
42
|
-
enrichment:
|
|
40
|
+
frac_oncogene_50kb: 0.21875
|
|
41
|
+
ci95: 0.14324
|
|
42
|
+
enrichment: 1.896
|
|
43
43
|
frac_genotoxic_cis: 0.0
|
|
44
|
-
median_dist_oncogene:
|
|
44
|
+
median_dist_oncogene: 145675
|
|
45
45
|
robust: false
|
|
46
46
|
vehicle_class:
|
|
47
47
|
lentiviral:
|
|
@@ -14,7 +14,7 @@ metrics:
|
|
|
14
14
|
means: "relative insertional-oncogenesis safety of the delivery/integration strategy. 1.0 = episomal/
|
|
15
15
|
non-integrating (no integration → no insertional mutagenesis); lower = an integrating vector whose insertion
|
|
16
16
|
sites fall nearer known proto-oncogenes."
|
|
17
|
-
computed: "for integrating vectors, from VISDB integration-site maps ×
|
|
17
|
+
computed: "for integrating vectors, from VISDB integration-site maps × CancerMine (CC0) oncogene
|
|
18
18
|
proximity (per-vector enrichment of integrations within 50 kb of an oncogene vs background)."
|
|
19
19
|
validation: "mechanistic proxy — NOT outcome-validated (the actual clonal-transformation rate is measured, not predicted)."
|
|
20
20
|
reference: "e.g. lentiviral ~0.48 (2.08× oncogene-proximity enrichment) vs episomal AAV 1.0."
|
|
@@ -115,16 +115,16 @@ oracles:
|
|
|
115
115
|
|
|
116
116
|
delivery_genotoxicity: # v5.2 WS-GENOTOX: computed integration-site oncogene-proximity
|
|
117
117
|
family: genome
|
|
118
|
-
version: "visdb+
|
|
118
|
+
version: "visdb+cancermine-2026"
|
|
119
119
|
output_kind: baseline # an observed-data comparator (integration catalogues), not generative
|
|
120
120
|
valid_for: "RELATIVE genotoxicity ordering of INTEGRATING vector classes via the observed enrichment of
|
|
121
|
-
integration sites near
|
|
122
|
-
|
|
121
|
+
integration sites near CancerMine (CC0) oncogenes (lentiviral vs gammaretroviral, from VISDB x CancerMine);
|
|
122
|
+
reproduces the integrating-vector-enriched-near-oncogenes signal from data"
|
|
123
123
|
not_valid_for: "the IN-VIVO clonal-expansion / leukemogenesis OUTCOME in a patient (a known-unknown); an
|
|
124
124
|
absolute per-insertion oncogenesis probability; non-integrating vectors (no insertional mechanism);
|
|
125
125
|
classes with too few catalogued sites (flagged extrapolating)"
|
|
126
126
|
generalizes_to_unseen_loci: false
|
|
127
|
-
license: "open (this work; VISDB 10.1093/nar/gkz867,
|
|
127
|
+
license: "open / CC0 (this work; VISDB 10.1093/nar/gkz867, CancerMine 10.1038/s41592-019-0422-y)"
|
|
128
128
|
|
|
129
129
|
capsid_epitope: # v5.3 WS-EPITOPE: computed capsid/envelope CD8 T-cell epitope load
|
|
130
130
|
family: protein_design
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Data card — position-effect supervision (v6.7 PEN-EXPRESS)
|
|
2
|
+
|
|
3
|
+
The unified table behind Stage H (`pen_stack/twin/data/position_effect.py`). One row = one integrated reporter /
|
|
4
|
+
element measurement. Schema: `dataset, organism, cell_type, chrom, pos, cassette, expression_raw, expression_z,
|
|
5
|
+
silenced, <chromatin features>`. `expression_z` is z-scored within (dataset × cassette).
|
|
6
|
+
|
|
7
|
+
## Dataset registry (verified accessions — 2026-06-19 verification pass)
|
|
8
|
+
|
|
9
|
+
| Dataset | Citation | DOI | Accession | Cell types | Status in v6.7 |
|
|
10
|
+
|---|---|---|---|---|---|
|
|
11
|
+
| **TRIP** | Akhtar et al., *Cell* 2013 | 10.1016/j.cell.2013.07.018 | GEO **GSE49806** (tetO) + **GSE49807** (mPGK); trip.nki.nl | mESC | **LIVE** (n=11,433) |
|
|
12
|
+
| PatchMPRA | Maricque, Chaudhari & Cohen, *Nat Biotechnol* 2019 | 10.1038/nbt.4285 | GEO (per paper) | mESC | registered, data-gated |
|
|
13
|
+
| MPIRE | Hong et al., *Nat Commun* 2024 | 10.1038/s41467-024-52599-6 | GEO **GSE223403**; github.com/claricehong/MPIRE_insulators | K562 | registered, data-gated |
|
|
14
|
+
| lentiMPRA | Agarwal et al., *Nature* **639**:411–420 (2025) | 10.1038/s41586-024-08430-9 | ENCODE + GEO; bioRxiv 2023.03.05.531189 | HepG2, K562, WTC11 | registered, data-gated |
|
|
15
|
+
| Leemans | Leemans et al., *Cell* 2019 | 10.1016/j.cell.2019.03.009 | GEO (per paper); van Steensel lab | K562 | registered, data-gated |
|
|
16
|
+
|
|
17
|
+
> The bioRxiv id `2023.03.05.531189` is **lentiMPRA's** (Agarwal → *Nature* 2025), not e2MPRA/ccMPRA — corrected
|
|
18
|
+
> in the 2026-06-19 citation verification pass.
|
|
19
|
+
|
|
20
|
+
## TRIP (the LIVE supervision)
|
|
21
|
+
|
|
22
|
+
- **What:** thousands of identical reporters integrated in parallel across the mESC genome; each row is a genomic
|
|
23
|
+
position with normalized expression → the position effect on an integrated cassette (the writing-relevant quantity).
|
|
24
|
+
- **Columns used:** `chrom, pos, promoter` (cassette: tetO 10,903 / mPGK 530), `expression` (log2, −13…+9),
|
|
25
|
+
`silenced` (low-expression tail, 25%), + 5 chromatin marks (H3K27ac, H3K4me1, H3K4me3, H3K9me3, H3K27me3).
|
|
26
|
+
- **Provenance:** same `trip_with_chromatin.parquet` the v3.x durability head trains on (regenerated by
|
|
27
|
+
`pen_stack/data/ingest_trip.py` + chromatin extraction).
|
|
28
|
+
- **License:** TRIP data is from a public GEO deposit (Akhtar 2013); see `DATA_LICENSES.md`. Raw data is gitignored
|
|
29
|
+
(`data/external/`), pulled from the VM for local runs; the shipped wheel carries the loaders + accessions, not the data.
|
|
30
|
+
|
|
31
|
+
## Honest limits
|
|
32
|
+
|
|
33
|
+
- **Mouse, single cell type.** TRIP is mESC. The model learns `chromatin → expression` (never a coordinate), so it
|
|
34
|
+
*applies* to a human epigenome — but the cross-cell-type **transfer** is unproven until ≥2 cell types are unified.
|
|
35
|
+
Until then the transfer track is **data-gated** (no fabricated number).
|
|
36
|
+
- **Reporter-based** (GFP-class), relative not absolute. Titer / % of normal stay known-unknowns.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Stage H — the learned, trained-conformal position-effect model (v6.7 PEN-EXPRESS)
|
|
2
|
+
|
|
3
|
+
Stage H predicts how strongly an integrated cassette expresses in its **chromatin context** (the position effect).
|
|
4
|
+
Through v6.6 this was a closed-form **heuristic** with a heuristic ±0.20 band that the code itself labelled *"NOT
|
|
5
|
+
a trained conformal interval"*, and which **failed** independent validation (ρ=0.12 vs Damdindorj 2014). v6.7
|
|
6
|
+
replaces the model behind Stage H with a **learned, decomposable, trained-conformal** one — wrapping the digital
|
|
7
|
+
twin, not rebuilding it.
|
|
8
|
+
|
|
9
|
+
## The model
|
|
10
|
+
|
|
11
|
+
`pen_stack/twin/position_effect.py::PositionEffectModel` is **factored and decomposable**:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
E_raw ≈ f_cassette(cassette) # the cassette's intrinsic strength (per-cassette mean)
|
|
15
|
+
+ g_context(chromatin features) # the position effect — a LightGBM on local chromatin
|
|
16
|
+
(+ h_interaction, reported) # does the context function differ by cassette? (separability)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`g_context` is supervised on the residual `E_raw − f_cassette`, so it learns the *position* effect on a scale
|
|
20
|
+
comparable across cassettes. A `silenced` classifier shares the chromatin features. The model is wrapped with the
|
|
21
|
+
**existing** `wgenome.uncertainty.ConformalRegressor` (chromosome-Mondrian split-conformal) and `wgenome.ood.OODDetector`
|
|
22
|
+
— so a prediction is a **calibrated interval that widens out of distribution**.
|
|
23
|
+
|
|
24
|
+
## Results (real, on TRIP supervision — Akhtar 2013, GEO GSE49806/49807, mESC, n=11,433)
|
|
25
|
+
|
|
26
|
+
Chromosome-blocked GroupKFold; paired bootstrap 95% CIs. *Every number is from a real CV run — no fabrication.*
|
|
27
|
+
|
|
28
|
+
| Metric | cassette-only | context-only (v3.x durability head) | **PEN-EXPRESS factored** | Δ vs head (CI) |
|
|
29
|
+
|---|---|---|---|---|
|
|
30
|
+
| Expression Spearman ρ | 0.032 | 0.427 | **0.469** | +0.041 [0.036, 0.046] ✅ excludes 0 |
|
|
31
|
+
| Silenced AUROC | — | 0.647 | 0.651 | +0.004 [0.001, 0.007] ✅ excludes 0 |
|
|
32
|
+
|
|
33
|
+
- **Gate G-M passed:** the factored model beats the durability head (CI excludes 0) → it serves behind Stage H.
|
|
34
|
+
- **Separability:** interaction adds **−0.002** R² → *additive `f_cassette + g_context` suffices at this N*
|
|
35
|
+
(reported honestly; the cassette term lifts expression, the silencing question is chromatin-driven).
|
|
36
|
+
- **Trained-conformal (the named gap, closed):** split-conformal (α=0.10) → **held-out coverage 0.885 vs 0.90
|
|
37
|
+
nominal** (within tolerance), qhat=5.50 on the log2 scale. Coverage is measured on a **half-chromosome held-out**
|
|
38
|
+
split, not on the calibration set.
|
|
39
|
+
|
|
40
|
+
## Stage H integration (`twin/outcome.py`)
|
|
41
|
+
|
|
42
|
+
`predict_outcome(design, cell_state)` now:
|
|
43
|
+
- **With a chromatin context** (`design["chromatin_features"]`) **and the model artifact present** → serves the
|
|
44
|
+
learned **trained-conformal** interval + `p_silenced` + OOD tier in a `position_effect` block; `stage_h_mode =
|
|
45
|
+
"learned_trained_conformal"`.
|
|
46
|
+
- **Without a context (or artifact)** → the closed-form heuristic band, exactly as before — **backward compatible**
|
|
47
|
+
(the v5.9 relative-scale contract and all prior tests are intact).
|
|
48
|
+
|
|
49
|
+
## Honest limits
|
|
50
|
+
|
|
51
|
+
- **Single-context supervision.** TRIP is mESC. The cross-cell-type **transfer** claim is **data-gated** — see
|
|
52
|
+
[tpe_bench.md](tpe_bench.md); no transfer number is fabricated until PatchMPRA/MPIRE/lentiMPRA/Leemans are fetched.
|
|
53
|
+
- **Public data cannot earn the ✅** (the v6.5 wall). v6.7 ships the learned+calibrated upgrade + the benchmark, not
|
|
54
|
+
a manufactured validated axis. Titer / absolute expression / phenotype stay **known-unknowns**.
|
|
55
|
+
- The model artifact (`models/position_effect.pkl`) is gitignored; regenerate it with
|
|
56
|
+
`python scripts/p1_build_position_effect.py` (the shipped calibration `configs/twin/position_effect_conformal.json`
|
|
57
|
+
is committed). Without the artifact, Stage H falls back to the heuristic.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# TPE-Bench — the position-effect / expression benchmark (v6.7)
|
|
2
|
+
|
|
3
|
+
The **expression** capability never had a held-out benchmark. TPE-Bench fills that gap as a track of the
|
|
4
|
+
[Genome-Writing Challenge](../benchmarks/genome_writing_challenge/): given a genomic **chromatin context** +
|
|
5
|
+
**cassette**, predict the **integrated-reporter expression** (and silencing), scored on a **sealed** split.
|
|
6
|
+
|
|
7
|
+
Location: `benchmarks/position_effect/` (`harness.py`, `split.json`, `SHA256SUMS`, `README.md`).
|
|
8
|
+
|
|
9
|
+
## Two tracks
|
|
10
|
+
|
|
11
|
+
| Track | Status | Held out | Metric |
|
|
12
|
+
|---|---|---|---|
|
|
13
|
+
| `chrom_holdout` | **LIVE** | whole chromosomes `chr2, chr5, chr14, chrX` (frozen + SHA-locked) | Spearman ρ + AUROC |
|
|
14
|
+
| `celltype_holdout` | **DATA-GATED** | leave-one-cell-type-out (the headline transfer test) | — |
|
|
15
|
+
|
|
16
|
+
`celltype_holdout` is the cross-cell-type transfer test. With one available position-effect cell type (mESC) it
|
|
17
|
+
returns `data_gated` **honestly** and activates once PatchMPRA / MPIRE / lentiMPRA / Leemans are fetched — **no
|
|
18
|
+
transfer number is fabricated**.
|
|
19
|
+
|
|
20
|
+
## Baseline leaderboard (`chrom_holdout`, sealed, n_test = 2257)
|
|
21
|
+
|
|
22
|
+
| Predictor | Expression ρ | Silenced AUROC |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| cassette-only | 0.178 | — |
|
|
25
|
+
| context-only (v3.x durability head) | 0.431 | 0.660 |
|
|
26
|
+
| **PEN-EXPRESS factored** | **0.475** | 0.660 |
|
|
27
|
+
|
|
28
|
+
The factored model's gain is on **expression** (ρ 0.431 → 0.475 on the sealed held-out chromosomes); the silencing
|
|
29
|
+
classifier matches the durability head (chromatin-driven) — reported honestly, not inflated.
|
|
30
|
+
|
|
31
|
+
## Discipline
|
|
32
|
+
|
|
33
|
+
- **Sealed + SHA-locked.** `split.json` is frozen and checksummed (`SHA256SUMS`) **before model selection**;
|
|
34
|
+
verify with `sha256sum -c benchmarks/position_effect/SHA256SUMS`.
|
|
35
|
+
- **Non-circular labels.** The label is the **measured** TRIP expression, never a submitter claim.
|
|
36
|
+
- **Leakage-controlled.** Held out by whole chromosome (nearby integrations share chromatin).
|
|
37
|
+
- **Honest data-gating.** The transfer track abstains until ≥2 cell types exist.
|
|
38
|
+
|
|
39
|
+
## Submit
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from benchmarks.position_effect.harness import Submission, evaluate
|
|
43
|
+
def predict(pi): # pi = {task_id, cassette, chromatin_features, instructions}; label hidden
|
|
44
|
+
return {"expression": 0.0, "p_silenced": 0.5}
|
|
45
|
+
print(evaluate(Submission("my-model", predict)))
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Reproduce the baselines: `python -c "from benchmarks.position_effect.harness import baseline_leaderboard as b; print(b())"`.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""PEN-STACK v3.0 - open infrastructure for genome writing."""
|
|
2
|
-
__version__ = "6.
|
|
2
|
+
__version__ = "6.7.0"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"""Safety annotations per 1 kb bin (Phase 1, Step 1.4).
|
|
1
|
+
"""Safety annotations per 1 kb bin (Phase 1, Step 1.4; v6.6 license-clean source).
|
|
2
2
|
|
|
3
|
-
Builds per-bin safety features from
|
|
4
|
-
DepMap CRISPRGeneEffect (essential genes), and GENCODE (gene/TSS distances):
|
|
3
|
+
Builds per-bin safety features from CancerMine (CC0; oncogene/TSG loci — the default, shipped) or COSMIC CGC
|
|
4
|
+
(local-only, bring-your-own-license), DepMap CRISPRGeneEffect (essential genes), and GENCODE (gene/TSS distances):
|
|
5
5
|
- dist_oncogene, dist_tsg, dist_essential, dist_tss (bp to nearest, via bedtools closest)
|
|
6
6
|
- genotoxic_cis flag (bins within a window of LMO2/MECOM/CCND2/PRDM16/HMGA2)
|
|
7
7
|
|
|
@@ -48,6 +48,30 @@ def load_cosmic(tsv: str) -> pd.DataFrame:
|
|
|
48
48
|
return df[["chrom", "start", "end", "GENE_SYMBOL", "role"]]
|
|
49
49
|
|
|
50
50
|
|
|
51
|
+
# v6.6: CancerMine (CC0) is the license-clean oncogene/TSG/driver source that REPLACES COSMIC CGC in the shipped
|
|
52
|
+
# artifact. Lever et al., Nat Methods 16:505-507 (2019), doi:10.1038/s41592-019-0422-y, CC0; Zenodo record 7689627.
|
|
53
|
+
# COSMIC stays available (load_cosmic) but OFF by default, for local enrichment under the user's own license (BYO).
|
|
54
|
+
CANCERMINE_URL = "https://zenodo.org/records/7689627/files/cancermine_collated.tsv?download=1"
|
|
55
|
+
_ROLE_MAP = {"Oncogene": "oncogene", "Tumor_Suppressor": "TSG", "Driver": "driver"}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def load_cancermine(tsv: str, genes: pd.DataFrame, min_citations: int = 3) -> pd.DataFrame:
|
|
59
|
+
"""CC0 oncogene/TSG/driver list. The collated file has one row per (gene, cancer, role) with a citation_count;
|
|
60
|
+
we aggregate per gene-role across cancers (sum citations), keep roles with >= min_citations, and map the HUGO
|
|
61
|
+
symbol -> genomic coordinates via GENCODE. Returns the SAME schema as load_cosmic (chrom,start,end,GENE_SYMBOL,
|
|
62
|
+
role) with the role string containing 'oncogene'/'TSG'/'driver' so the downstream filters are unchanged."""
|
|
63
|
+
cm = pd.read_csv(tsv, sep="\t", dtype=str)
|
|
64
|
+
cm["cites"] = pd.to_numeric(cm.get("citation_count"), errors="coerce").fillna(0)
|
|
65
|
+
agg = cm.groupby(["gene_normalized", "role"], as_index=False)["cites"].sum()
|
|
66
|
+
agg = agg[agg["cites"] >= float(min_citations)]
|
|
67
|
+
agg["rn"] = agg["role"].map(_ROLE_MAP).fillna(agg["role"])
|
|
68
|
+
roles = (agg.groupby("gene_normalized")["rn"]
|
|
69
|
+
.apply(lambda s: ",".join(sorted(set(s)))).reset_index(name="role"))
|
|
70
|
+
g = genes[["gene_name", "chrom", "start", "end"]].drop_duplicates("gene_name")
|
|
71
|
+
m = roles.merge(g, left_on="gene_normalized", right_on="gene_name", how="inner")
|
|
72
|
+
return m.rename(columns={"gene_normalized": "GENE_SYMBOL"})[["chrom", "start", "end", "GENE_SYMBOL", "role"]]
|
|
73
|
+
|
|
74
|
+
|
|
51
75
|
def load_depmap_essential(csv: str, thresh: float = -0.5) -> set[str]:
|
|
52
76
|
"""Common-essential genes: mean Chronos effect across cell lines < thresh."""
|
|
53
77
|
df = pd.read_csv(csv, index_col=0)
|
|
@@ -112,17 +136,24 @@ def nearest_dist(bins_bed: pybedtools.BedTool, feat_df: pd.DataFrame, name: str)
|
|
|
112
136
|
return out.groupby(["chrom", "start"], as_index=False)[name].min()
|
|
113
137
|
|
|
114
138
|
|
|
115
|
-
def build(bin_grid: str,
|
|
116
|
-
|
|
139
|
+
def build(bin_grid: str, depmap_csv: str, gencode_dest: str, sizes_tsv: str, out_parquet: str, *,
|
|
140
|
+
source: str = "cancermine", cancermine_tsv: str | None = None, cosmic_tsv: str | None = None,
|
|
141
|
+
min_citations: int = 3) -> pd.DataFrame:
|
|
142
|
+
"""Build per-bin safety features. `source` selects the LICENSE-CLEAN oncogene/TSG list: 'cancermine' (CC0,
|
|
143
|
+
default, shipped) or 'cosmic' (local-only, under the user's own license — bring-your-own-license enrichment)."""
|
|
117
144
|
grid = pd.read_parquet(bin_grid)[["chrom", "start", "bin"]]
|
|
118
145
|
bins_bed = _bed(grid.assign(end=grid["start"] + BIN_BP)).sort()
|
|
119
146
|
|
|
120
|
-
cosmic = load_cosmic(cosmic_tsv)
|
|
121
|
-
onco = cosmic[cosmic["role"].str.contains("oncogene", case=False, na=False)]
|
|
122
|
-
tsg = cosmic[cosmic["role"].str.contains("TSG", case=False, na=False)]
|
|
123
|
-
|
|
124
147
|
gtf = download_gencode(gencode_dest)
|
|
125
148
|
genes = parse_gencode_genes(gtf)
|
|
149
|
+
|
|
150
|
+
if source == "cosmic":
|
|
151
|
+
cg = load_cosmic(cosmic_tsv)
|
|
152
|
+
else: # default: CancerMine (CC0)
|
|
153
|
+
cg = load_cancermine(cancermine_tsv, genes, min_citations=min_citations)
|
|
154
|
+
onco = cg[cg["role"].str.contains("oncogene", case=False, na=False)]
|
|
155
|
+
tsg = cg[cg["role"].str.contains("TSG", case=False, na=False)]
|
|
156
|
+
|
|
126
157
|
ess_syms = load_depmap_essential(depmap_csv)
|
|
127
158
|
ess = genes[genes["gene_name"].isin(ess_syms)]
|
|
128
159
|
|
|
@@ -148,15 +179,21 @@ def build(bin_grid: str, cosmic_tsv: str, depmap_csv: str, gencode_dest: str,
|
|
|
148
179
|
def main() -> None:
|
|
149
180
|
ap = argparse.ArgumentParser()
|
|
150
181
|
ap.add_argument("--bin-grid", default="/data/features/bin_grid_1kb.parquet")
|
|
182
|
+
ap.add_argument("--source", choices=["cancermine", "cosmic"], default="cancermine",
|
|
183
|
+
help="oncogene/TSG source: cancermine (CC0, shipped default) or cosmic (local-only BYO-license)")
|
|
184
|
+
ap.add_argument("--cancermine", default="/data/external/cancermine_collated.tsv")
|
|
185
|
+
ap.add_argument("--min-citations", type=int, default=3,
|
|
186
|
+
help="CancerMine per-gene-role citation threshold (3 = validated precision: safety AUROC 0.74)")
|
|
151
187
|
ap.add_argument("--cosmic", default="/data/external/Cosmic_CancerGeneCensus_v104_GRCh38.tsv")
|
|
152
188
|
ap.add_argument("--depmap", default="/data/external/CRISPRGeneEffect.csv")
|
|
153
189
|
ap.add_argument("--gencode", default="/data/raw/gencode.v46.basic.gtf.gz")
|
|
154
190
|
ap.add_argument("--sizes", default="/data/raw/hg38.chrom.sizes")
|
|
155
191
|
ap.add_argument("--out", default="/data/features/safety_annot.parquet")
|
|
156
192
|
a = ap.parse_args()
|
|
157
|
-
df = build(a.bin_grid, a.
|
|
193
|
+
df = build(a.bin_grid, a.depmap, a.gencode, a.sizes, a.out, source=a.source,
|
|
194
|
+
cancermine_tsv=a.cancermine, cosmic_tsv=a.cosmic, min_citations=a.min_citations)
|
|
158
195
|
n_onco = (df["dist_oncogene"] == 0).sum()
|
|
159
|
-
print(f"safety_annot bins={len(df)} cols={[c for c in df.columns if c.startswith('dist') or c=='genotoxic_cis']}")
|
|
196
|
+
print(f"safety_annot[{a.source}] bins={len(df)} cols={[c for c in df.columns if c.startswith('dist') or c=='genotoxic_cis']}")
|
|
160
197
|
print(f"bins in an oncogene={n_onco} genotoxic_cis bins={int(df['genotoxic_cis'].sum())}")
|
|
161
198
|
|
|
162
199
|
|