factorforge-cds 3.5.10__tar.gz → 3.5.12__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.
- {factorforge_cds-3.5.10/src/factorforge_cds.egg-info → factorforge_cds-3.5.12}/PKG-INFO +33 -7
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/README.md +25 -6
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/pyproject.toml +12 -2
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/analysis/metrics.py +38 -11
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/cli/main.py +2 -0
- factorforge_cds-3.5.12/src/factorforge/cli/structure_cli.py +157 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/__init__.py +13 -0
- factorforge_cds-3.5.12/src/factorforge/engines/dp_v2_4.py +870 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/registry/version_manifest.json +12 -3
- factorforge_cds-3.5.12/src/factorforge/structure/__init__.py +45 -0
- factorforge_cds-3.5.12/src/factorforge/structure/esm_annotator.py +249 -0
- factorforge_cds-3.5.12/src/factorforge/structure/interpro_sidecar_fetcher.py +321 -0
- factorforge_cds-3.5.12/src/factorforge/structure/uniprot_sidecar_fetcher.py +313 -0
- factorforge_cds-3.5.12/src/factorforge/structure/viewer_bridge.py +286 -0
- factorforge_cds-3.5.12/src/factorforge/validation/__init__.py +30 -0
- factorforge_cds-3.5.12/src/factorforge/validation/dp_4dp_comparison.py +1441 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12/src/factorforge_cds.egg-info}/PKG-INFO +33 -7
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge_cds.egg-info/SOURCES.txt +20 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge_cds.egg-info/requires.txt +10 -0
- factorforge_cds-3.5.12/tests/test_benchmark_dnachisel.py +46 -0
- factorforge_cds-3.5.12/tests/test_conda_source_hash.py +31 -0
- factorforge_cds-3.5.12/tests/test_dp_4dp_comparison.py +369 -0
- factorforge_cds-3.5.12/tests/test_dp_v2_4_0.py +249 -0
- factorforge_cds-3.5.12/tests/test_dp_v2_4_review.py +108 -0
- factorforge_cds-3.5.12/tests/test_esm_annotator.py +74 -0
- factorforge_cds-3.5.12/tests/test_hpx_viewer_review.py +59 -0
- factorforge_cds-3.5.12/tests/test_installed_distribution_smoke.py +72 -0
- factorforge_cds-3.5.12/tests/test_interpro_sidecar_fetcher.py +196 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_multi_engine_governance.py +3 -3
- factorforge_cds-3.5.12/tests/test_public_audit_scope.py +22 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_scientific_web_397.py +8 -3
- factorforge_cds-3.5.12/tests/test_structure_cli.py +126 -0
- factorforge_cds-3.5.12/tests/test_uniprot_sidecar_fetcher.py +191 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_version_manifest.py +3 -2
- factorforge_cds-3.5.12/tests/test_viewer_bridge.py +149 -0
- factorforge_cds-3.5.10/src/factorforge/structure/__init__.py +0 -11
- factorforge_cds-3.5.10/src/factorforge/validation/__init__.py +0 -3
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/LICENSE +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/setup.cfg +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/__main__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/analysis/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/analysis/feasibility.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/analysis/sequence_risks.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/benchmark/models.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/benchmark/runner.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/cli/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/cli/benchmark_cli.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/cli/legacy_cli.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/closed_loop/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/closed_loop/contracts.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/closed_loop/ledger.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/closed_loop/readiness.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/codon/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/codon/allocator.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/codon/policy.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/codon/qa.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/codon/twin_generator.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/constraints/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/constraints/type_iis.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/core/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/core/experiment.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/core/host_model.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/core/interfaces/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/core/interfaces/exporter.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/core/interfaces/optimizer.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/core/interfaces/validator.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/core/policy.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/core/reranker.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/core/slate_engine.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/core/slate_generator.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/human_stemcell_codons.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/nbenthamiana_codons.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/nbenthamiana_golden_set.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/ntabacum_codons.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/profiles/human_stemcell_derived_codons.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/profiles/human_stemcell_policy.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/profiles/nbev11_cds_all_derived_codons.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/profiles/nbev11_cds_all_derived_filtered_stats.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/profiles/nbev11_cds_all_derived_manifest.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/profiles/nbev11_cds_hc_derived_codons.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/profiles/nbev11_cds_hc_derived_filtered_stats.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/profiles/nbev11_cds_hc_derived_manifest.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/profiles/qld183_v103_derived_codons.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/profiles/qld183_v103_derived_manifest.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/profiles/qld183_v103_filtered_stats.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/reference/reference_policy_manifest.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/templates/high_expression.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/templates/standard_expression.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/data/wolffia_globosa_codons.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/database.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/db/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/db/connector.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/design_review.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/discovery/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/discovery/acquisition.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/discovery/acquisition_logger.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/discovery/filter.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/discovery/generator.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/discovery/panel_builder.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/discovery/schemas.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/discovery/slate.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/discovery/traits.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/balanced_optimizer.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/dp_adapter.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/dp_v2.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/dp_v2_1.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/dp_v2_1_1.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/dp_v2_2.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/dp_v2_3.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/lm/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/lm/adapter.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/lm/diagnostics.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/lm/inference.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/lm/models/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/lm/models/mbart_codon.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/lm/tokenizer/control_tokenizer.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/local_rewriter.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/profile/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/profile/codon_table_builder.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/profile/construct_builder.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/profile/exporter.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/profile/optimizer.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/profile/pipeline.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/profile/rules/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/profile/rules/domesticator.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/profile/rules/reverse_translator.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/profile/rules/rule_engine.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/profile/scoring.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/profile/scoring_ml.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/profile/utils.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/profile/validator.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/registry.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/sllm/adapters.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/sllm/automaton.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/sllm/compiler.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/sllm/data/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/sllm/data/corpus_builder.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/sllm/data/tokenizer.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/sllm/decoder.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/sllm/interfaces.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/sllm/model/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/sllm/model/arch.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/sllm/model/baselines.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/sllm/model/export_onnx.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/stemcell_3dp.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/structural_pause.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/structure_web.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/engines/targeted_remediator.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/evaluation/evaluator.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/evaluation/evidence_logger.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/evaluation/metrics.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/evaluation/models.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/guards/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/guards/initiation_mfe.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/guards/plant_rna_guards.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/io/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/io/fasta.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/io/package_compiler.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/io/validation.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/learning/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/learning/ranker.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/nbfold/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/nbfold/annotations.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/nbfold/bridge.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/nbfold/cli.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/nbfold/contracts.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/nbfold/pipeline.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/pipeline/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/pipeline/design_pipeline.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/profiles/profile_snapshot.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/protein_risk/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/protein_risk/annotate.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/protein_risk/kd_scale.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/protein_risk/risk_classifier.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/protein_risk/sp_predict.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/protein_risk/tm_predict.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/registry/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/registry/method_registry.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/registry/model_registry.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/registry/registry_loader.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/registry/versioning.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/review/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/review/evaluation_integrity.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/rules/models.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/rules/registry.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/schemas/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/schemas/design_package.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/schemas/design_package.schema.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/schemas/evidence.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/schemas/run_config.schema.json +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/scoring/quantization.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/sops/config.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/structure/auto_annotator.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/structure/auto_resolver.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/telemetry/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/telemetry/gcs_reconciliation.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/telemetry/training_logger.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/utils/__init__.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/utils/construct_id.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/utils/exceptions.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/utils/restriction_sites.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/utils/sequence_identity.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/utils/sequence_validator.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/utils/validation.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/validation/cli.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/validation/hub.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/validation/package_generator.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/validation/tradeoff_suite.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/validation_registry.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge/validation_report.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge_cds.egg-info/dependency_links.txt +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge_cds.egg-info/entry_points.txt +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/src/factorforge_cds.egg-info/top_level.txt +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_3dp_review_regressions.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_3dp_validation_suite.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_auto_annotator.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_baselines.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_benchmark_cli_output_guard.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_benchmark_codon_table_metadata.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_benchmark_harness.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_benchmark_regression.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_benchmark_scoring.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_benchmark_smoke.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_cai.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_candidate_review_safety.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_codon_table_manifest.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_cross_engine_evaluation.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_database.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_database_configuration.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_db_connector.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_design_package_schema.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_design_package_semantics.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_design_package_serialization.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_design_review.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_docs_consistency.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_dp_v2_1_1.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_dp_v2_1_initiation.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_dp_v2_2_0.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_dp_v2_3_0.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_durable_reconciliation.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_enterprise_integration_396.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_fasta_io.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_gc_content.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_host_profile_metadata.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_hpx_viewer.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_initiation_mfe.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_iupac_validation.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_job350_codon_twins.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_job351_closed_loop_foundation.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_job355_design_experiment.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_learning_workflow_boundary.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_legacy_cli.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_lm_alpha_contract.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_local_rewriter.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_math_v2_dp_optimality.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_nbfold_phase_c.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_nbfold_phase_c_benchmark.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_nbfold_pipeline.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_no_raw_sequence_logging.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_oct23_review.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_onnx_adapter_contract.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_openbio_missing_metric_contract.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_optional_postgres.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_parameter_registry.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_partial_dp_rescue.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_plant_rna_guards.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_policy_type_iis_targets.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_prepare_lm_dataset.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_protein_risk.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_public_surface_scanner.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_quantized_scoring.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_registry_production_sync.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_restriction_sites.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_rule_registry.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_sequence_validator.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_sllm_biological_pipeline.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_slm_decoder.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_slm_interface.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_sop_profile.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_stemcell_3dp.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_structural_pause.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_suite_capability_compat.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_training_logger.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_translation_integrity.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_validation_contract_compat.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_validation_registry.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_validation_report.py +0 -0
- {factorforge_cds-3.5.10 → factorforge_cds-3.5.12}/tests/test_worked_example.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: factorforge-cds
|
|
3
|
-
Version: 3.5.
|
|
3
|
+
Version: 3.5.12
|
|
4
4
|
Summary: FactorForge - open-source CDS design and pre-synthesis sequence review by Eijex.
|
|
5
5
|
Author-email: Eijex <eijex.lab@gmail.com>
|
|
6
6
|
License-Expression: AGPL-3.0-only
|
|
@@ -34,6 +34,13 @@ Provides-Extra: ml
|
|
|
34
34
|
Requires-Dist: transformers>=4.40; extra == "ml"
|
|
35
35
|
Requires-Dist: torch>=2.0; extra == "ml"
|
|
36
36
|
Requires-Dist: onnxruntime>=1.16; extra == "ml"
|
|
37
|
+
Provides-Extra: acceleration
|
|
38
|
+
Requires-Dist: pyahocorasick>=2.3.1; extra == "acceleration"
|
|
39
|
+
Provides-Extra: benchmark
|
|
40
|
+
Requires-Dist: dnachisel>=3.2.16; extra == "benchmark"
|
|
41
|
+
Requires-Dist: scipy>=1.17; extra == "benchmark"
|
|
42
|
+
Provides-Extra: ml-structure
|
|
43
|
+
Requires-Dist: fair-esm>=2.0.0; extra == "ml-structure"
|
|
37
44
|
Dynamic: license-file
|
|
38
45
|
|
|
39
46
|
# FactorForge
|
|
@@ -43,6 +50,7 @@ Dynamic: license-file
|
|
|
43
50
|
[](LICENSE)
|
|
44
51
|
[](https://www.python.org/)
|
|
45
52
|
[](https://pypi.org/project/factorforge-cds/)
|
|
53
|
+
[](https://anaconda.org/bioconda/factorforge-cds)
|
|
46
54
|
[](https://github.com/eijex/factorforge-cds/actions/workflows/ci.yml)
|
|
47
55
|
[](https://codecov.io/gh/eijex/factorforge-cds)
|
|
48
56
|
[](https://doi.org/10.5281/zenodo.20407330)
|
|
@@ -52,7 +60,7 @@ Dynamic: license-file
|
|
|
52
60
|
|
|
53
61
|
FactorForge performs deterministic CDS design with CAI/GC metrics, PolyA-signal screening, and Golden Gate/MoClo-aware checks. It is positioned as a pre-synthesis review harness: it helps teams generate reproducible CDS candidates, inspect assembly-relevant sequence constraints, and package design metadata before downstream synthesis, cloning, or experimental review. Primary support: *N. benthamiana* (agroinfiltration). Experimental host context: Tobacco BY-2 (`--host by2`).
|
|
54
62
|
|
|
55
|
-
FactorForge v3.5.
|
|
63
|
+
FactorForge v3.5.12 uses independently versioned engines:
|
|
56
64
|
|
|
57
65
|
| Generation | Engine | Version | Availability |
|
|
58
66
|
|---|---|---:|---|
|
|
@@ -69,18 +77,31 @@ FactorForge v3.5.10 uses independently versioned engines:
|
|
|
69
77
|
## Quick Start
|
|
70
78
|
|
|
71
79
|
```bash
|
|
80
|
+
# Bioconda: Linux/macOS, or Ubuntu inside WSL on Windows
|
|
81
|
+
conda create -n factorforge-review --override-channels -c conda-forge -c bioconda --strict-channel-priority python=3.11 factorforge-cds
|
|
82
|
+
conda activate factorforge-review
|
|
83
|
+
|
|
84
|
+
# Via PyPI
|
|
72
85
|
pip install factorforge-cds
|
|
86
|
+
|
|
87
|
+
# Run optimization
|
|
73
88
|
factorforge optimize my_protein.fasta -o output.fasta
|
|
74
89
|
```
|
|
75
90
|
|
|
76
91
|
Or use the **[web app](https://factorforge.eijex.com)** — no installation required.
|
|
77
92
|
|
|
93
|
+
Bioconda does not support native Windows. Use WSL for that installation route;
|
|
94
|
+
see [installation and reviewer checks](docs/getting-started.md) for the tested
|
|
95
|
+
version, platform limitations and installed-package smoke command. Local DP
|
|
96
|
+
optimization needs no Neon database, GCP account or GPU.
|
|
97
|
+
|
|
78
98
|
---
|
|
79
99
|
|
|
80
100
|
## Access Options
|
|
81
101
|
|
|
82
102
|
| Method | Description | Link |
|
|
83
103
|
|--------|-------------|------|
|
|
104
|
+
| **Bioconda** | Linux/macOS; WSL on Windows | [Isolated installation](docs/getting-started.md#via-bioconda-recommended-for-bioinformatics) |
|
|
84
105
|
| **Web App** | No installation, demo & light use | [factorforge.eijex.com](https://factorforge.eijex.com) |
|
|
85
106
|
| **CLI / Python** | Local use, batch processing, data privacy | `pip install factorforge-cds` |
|
|
86
107
|
| **Docker** | Full web interface locally | `docker pull ghcr.io/eijex/factorforge-cds:latest` |
|
|
@@ -134,10 +155,15 @@ FactorForge outputs are **in-silico only** and have not been experimentally vali
|
|
|
134
155
|
## Citing
|
|
135
156
|
|
|
136
157
|
```
|
|
137
|
-
FactorForge v3.5.
|
|
158
|
+
FactorForge v3.5.12 (2026). Open-source constraint-based CDS design and sequence review.
|
|
138
159
|
Eijex. https://github.com/eijex/factorforge-cds
|
|
139
160
|
```
|
|
140
161
|
|
|
162
|
+
The [v3.5.11 software archive](https://doi.org/10.5281/zenodo.23631740)
|
|
163
|
+
and the [accompanying computational preprint](https://doi.org/10.20944/preprints202610.3128.v1)
|
|
164
|
+
are separate citations. The preprint reports historical v3.2.0/v3.3.0 executions,
|
|
165
|
+
not a benchmark of every later software release.
|
|
166
|
+
|
|
141
167
|
---
|
|
142
168
|
|
|
143
169
|
## Maintainer
|
|
@@ -189,11 +215,11 @@ GNU Affero General Public License v3.0 — see [LICENSE](LICENSE).
|
|
|
189
215
|
|
|
190
216
|
## Testing status
|
|
191
217
|
|
|
192
|
-
The web UI
|
|
218
|
+
The web UI labels watermark as disabled and distinguishes the sequence-only baseline from retained experimental structure-conditioned testing. The local reviewed workflow supports 1DP-only or paired 3DP mode. General 3DP/4DP web access is paused by default; local research availability is not a biological-performance claim. See [web UI boundaries](web/README.md).
|
|
193
219
|
|
|
194
|
-
##
|
|
220
|
+
## Experimental 3DP web access (paused by default)
|
|
195
221
|
|
|
196
|
-
The
|
|
222
|
+
The public form offers 1DP. General 3DP/4DP web access is paused pending evaluation and collaborator feedback. Research deployments require both a deliberate web build opt-in (`ENABLE_EXPERIMENTAL_STRUCTURE_WEB`) and server opt-in (`FACTORFORGE_EXPERIMENTAL_3DP_ENABLED=true`); these flags are availability controls, not authentication or research consent. Without the server flag, structure generation, recommendation and resolution requests fail with `EXPERIMENTAL_STRUCTURE_DISABLED`. Local experimental implementations are retained. See [research boundaries](docs/experimental-structure.md).
|
|
197
223
|
|
|
198
224
|
Limits: 3–300 amino acids, structure content 250 KB, HTTP JSON body 1 MB. Both candidates use the configured codon reference, requested GC and canonical motif exclusions plus custom additions. Invalid inputs and infeasible candidates fail without a baseline fallback. Existing sequence-only settings and API requests remain supported. 3DP uses its explicit DP settings and does not apply Kozak, TpA, template or seed transformations. SOP checks are reported for both candidates; regeneration is manual and never silently changes mode. Watermark stays disabled.
|
|
199
225
|
|
|
@@ -201,7 +227,7 @@ This is stateless computational testing, with no external service dependencies o
|
|
|
201
227
|
|
|
202
228
|
## Current public policy UI (2026-10-12)
|
|
203
229
|
|
|
204
|
-
Custom SOP management is paused. The built-in FactorForge default policy is applied; upload/export/preset/editing controls are hidden and disabled. Their code and previous browser configuration remain available for later reactivation through ENABLE_CUSTOM_SOP. Saved custom SOPs are ignored without deletion. 1DP
|
|
230
|
+
Custom SOP management is paused. The built-in FactorForge default policy is applied; upload/export/preset/editing controls are hidden and disabled. Their code and previous browser configuration remain available for later reactivation through ENABLE_CUSTOM_SOP. Saved custom SOPs are ignored without deletion. 1DP remains active; general 3DP selection and API structure actions are disabled by default. Their retained research contract requires explicit deployment opt-in. This supersedes the earlier public SOP upload/export instructions.
|
|
205
231
|
|
|
206
232
|
### Scientific web observations
|
|
207
233
|
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
[](https://www.python.org/)
|
|
7
7
|
[](https://pypi.org/project/factorforge-cds/)
|
|
8
|
+
[](https://anaconda.org/bioconda/factorforge-cds)
|
|
8
9
|
[](https://github.com/eijex/factorforge-cds/actions/workflows/ci.yml)
|
|
9
10
|
[](https://codecov.io/gh/eijex/factorforge-cds)
|
|
10
11
|
[](https://doi.org/10.5281/zenodo.20407330)
|
|
@@ -14,7 +15,7 @@
|
|
|
14
15
|
|
|
15
16
|
FactorForge performs deterministic CDS design with CAI/GC metrics, PolyA-signal screening, and Golden Gate/MoClo-aware checks. It is positioned as a pre-synthesis review harness: it helps teams generate reproducible CDS candidates, inspect assembly-relevant sequence constraints, and package design metadata before downstream synthesis, cloning, or experimental review. Primary support: *N. benthamiana* (agroinfiltration). Experimental host context: Tobacco BY-2 (`--host by2`).
|
|
16
17
|
|
|
17
|
-
FactorForge v3.5.
|
|
18
|
+
FactorForge v3.5.12 uses independently versioned engines:
|
|
18
19
|
|
|
19
20
|
| Generation | Engine | Version | Availability |
|
|
20
21
|
|---|---|---:|---|
|
|
@@ -31,18 +32,31 @@ FactorForge v3.5.10 uses independently versioned engines:
|
|
|
31
32
|
## Quick Start
|
|
32
33
|
|
|
33
34
|
```bash
|
|
35
|
+
# Bioconda: Linux/macOS, or Ubuntu inside WSL on Windows
|
|
36
|
+
conda create -n factorforge-review --override-channels -c conda-forge -c bioconda --strict-channel-priority python=3.11 factorforge-cds
|
|
37
|
+
conda activate factorforge-review
|
|
38
|
+
|
|
39
|
+
# Via PyPI
|
|
34
40
|
pip install factorforge-cds
|
|
41
|
+
|
|
42
|
+
# Run optimization
|
|
35
43
|
factorforge optimize my_protein.fasta -o output.fasta
|
|
36
44
|
```
|
|
37
45
|
|
|
38
46
|
Or use the **[web app](https://factorforge.eijex.com)** — no installation required.
|
|
39
47
|
|
|
48
|
+
Bioconda does not support native Windows. Use WSL for that installation route;
|
|
49
|
+
see [installation and reviewer checks](docs/getting-started.md) for the tested
|
|
50
|
+
version, platform limitations and installed-package smoke command. Local DP
|
|
51
|
+
optimization needs no Neon database, GCP account or GPU.
|
|
52
|
+
|
|
40
53
|
---
|
|
41
54
|
|
|
42
55
|
## Access Options
|
|
43
56
|
|
|
44
57
|
| Method | Description | Link |
|
|
45
58
|
|--------|-------------|------|
|
|
59
|
+
| **Bioconda** | Linux/macOS; WSL on Windows | [Isolated installation](docs/getting-started.md#via-bioconda-recommended-for-bioinformatics) |
|
|
46
60
|
| **Web App** | No installation, demo & light use | [factorforge.eijex.com](https://factorforge.eijex.com) |
|
|
47
61
|
| **CLI / Python** | Local use, batch processing, data privacy | `pip install factorforge-cds` |
|
|
48
62
|
| **Docker** | Full web interface locally | `docker pull ghcr.io/eijex/factorforge-cds:latest` |
|
|
@@ -96,10 +110,15 @@ FactorForge outputs are **in-silico only** and have not been experimentally vali
|
|
|
96
110
|
## Citing
|
|
97
111
|
|
|
98
112
|
```
|
|
99
|
-
FactorForge v3.5.
|
|
113
|
+
FactorForge v3.5.12 (2026). Open-source constraint-based CDS design and sequence review.
|
|
100
114
|
Eijex. https://github.com/eijex/factorforge-cds
|
|
101
115
|
```
|
|
102
116
|
|
|
117
|
+
The [v3.5.11 software archive](https://doi.org/10.5281/zenodo.23631740)
|
|
118
|
+
and the [accompanying computational preprint](https://doi.org/10.20944/preprints202610.3128.v1)
|
|
119
|
+
are separate citations. The preprint reports historical v3.2.0/v3.3.0 executions,
|
|
120
|
+
not a benchmark of every later software release.
|
|
121
|
+
|
|
103
122
|
---
|
|
104
123
|
|
|
105
124
|
## Maintainer
|
|
@@ -151,11 +170,11 @@ GNU Affero General Public License v3.0 — see [LICENSE](LICENSE).
|
|
|
151
170
|
|
|
152
171
|
## Testing status
|
|
153
172
|
|
|
154
|
-
The web UI
|
|
173
|
+
The web UI labels watermark as disabled and distinguishes the sequence-only baseline from retained experimental structure-conditioned testing. The local reviewed workflow supports 1DP-only or paired 3DP mode. General 3DP/4DP web access is paused by default; local research availability is not a biological-performance claim. See [web UI boundaries](web/README.md).
|
|
155
174
|
|
|
156
|
-
##
|
|
175
|
+
## Experimental 3DP web access (paused by default)
|
|
157
176
|
|
|
158
|
-
The
|
|
177
|
+
The public form offers 1DP. General 3DP/4DP web access is paused pending evaluation and collaborator feedback. Research deployments require both a deliberate web build opt-in (`ENABLE_EXPERIMENTAL_STRUCTURE_WEB`) and server opt-in (`FACTORFORGE_EXPERIMENTAL_3DP_ENABLED=true`); these flags are availability controls, not authentication or research consent. Without the server flag, structure generation, recommendation and resolution requests fail with `EXPERIMENTAL_STRUCTURE_DISABLED`. Local experimental implementations are retained. See [research boundaries](docs/experimental-structure.md).
|
|
159
178
|
|
|
160
179
|
Limits: 3–300 amino acids, structure content 250 KB, HTTP JSON body 1 MB. Both candidates use the configured codon reference, requested GC and canonical motif exclusions plus custom additions. Invalid inputs and infeasible candidates fail without a baseline fallback. Existing sequence-only settings and API requests remain supported. 3DP uses its explicit DP settings and does not apply Kozak, TpA, template or seed transformations. SOP checks are reported for both candidates; regeneration is manual and never silently changes mode. Watermark stays disabled.
|
|
161
180
|
|
|
@@ -163,7 +182,7 @@ This is stateless computational testing, with no external service dependencies o
|
|
|
163
182
|
|
|
164
183
|
## Current public policy UI (2026-10-12)
|
|
165
184
|
|
|
166
|
-
Custom SOP management is paused. The built-in FactorForge default policy is applied; upload/export/preset/editing controls are hidden and disabled. Their code and previous browser configuration remain available for later reactivation through ENABLE_CUSTOM_SOP. Saved custom SOPs are ignored without deletion. 1DP
|
|
185
|
+
Custom SOP management is paused. The built-in FactorForge default policy is applied; upload/export/preset/editing controls are hidden and disabled. Their code and previous browser configuration remain available for later reactivation through ENABLE_CUSTOM_SOP. Saved custom SOPs are ignored without deletion. 1DP remains active; general 3DP selection and API structure actions are disabled by default. Their retained research contract requires explicit deployment opt-in. This supersedes the earlier public SOP upload/export instructions.
|
|
167
186
|
|
|
168
187
|
### Scientific web observations
|
|
169
188
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["setuptools>=
|
|
2
|
+
requires = ["setuptools>=77.0.3", "wheel"]
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "factorforge-cds"
|
|
7
|
-
version = "3.5.
|
|
7
|
+
version = "3.5.12"
|
|
8
8
|
description = "FactorForge - open-source CDS design and pre-synthesis sequence review by Eijex."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "AGPL-3.0-only"
|
|
@@ -45,6 +45,16 @@ ml = [
|
|
|
45
45
|
"torch>=2.0",
|
|
46
46
|
"onnxruntime>=1.16",
|
|
47
47
|
]
|
|
48
|
+
acceleration = [
|
|
49
|
+
"pyahocorasick>=2.3.1",
|
|
50
|
+
]
|
|
51
|
+
benchmark = [
|
|
52
|
+
"dnachisel>=3.2.16",
|
|
53
|
+
"scipy>=1.17",
|
|
54
|
+
]
|
|
55
|
+
ml-structure = [
|
|
56
|
+
"fair-esm>=2.0.0",
|
|
57
|
+
]
|
|
48
58
|
|
|
49
59
|
[project.urls]
|
|
50
60
|
Homepage = "https://factorforge.eijex.com"
|
|
@@ -408,18 +408,45 @@ def detect_repeats(sequence: str) -> list[dict[str, Any]]:
|
|
|
408
408
|
|
|
409
409
|
|
|
410
410
|
def detect_forbidden_motifs(sequence: str, motifs: list[str]) -> list[dict[str, Any]]:
|
|
411
|
-
"""Find all exact forbidden motif occurrences.
|
|
411
|
+
"""Find all exact forbidden motif occurrences.
|
|
412
|
+
|
|
413
|
+
Uses pyahocorasick C-automaton when available for O(N + M) single-pass scanning;
|
|
414
|
+
falls back transparently to pure Python string searching if unavailable.
|
|
415
|
+
"""
|
|
412
416
|
seq = _normalize_dna(sequence)
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
417
|
+
if not seq or not motifs:
|
|
418
|
+
return []
|
|
419
|
+
|
|
420
|
+
try:
|
|
421
|
+
import ahocorasick
|
|
422
|
+
|
|
423
|
+
A = ahocorasick.Automaton()
|
|
424
|
+
has_motif = False
|
|
425
|
+
for m in motifs:
|
|
426
|
+
norm = _normalize_dna(m)
|
|
427
|
+
if norm:
|
|
428
|
+
A.add_word(norm, norm)
|
|
429
|
+
has_motif = True
|
|
430
|
+
if not has_motif:
|
|
431
|
+
return []
|
|
432
|
+
A.make_automaton()
|
|
433
|
+
|
|
434
|
+
findings: list[dict[str, Any]] = []
|
|
435
|
+
for end_idx, norm in A.iter(seq):
|
|
436
|
+
start = end_idx - len(norm) + 1
|
|
437
|
+
findings.append({"start": start, "end": end_idx + 1, "motif": norm})
|
|
438
|
+
return sorted(findings, key=lambda x: (x["start"], x["end"]))
|
|
439
|
+
except ImportError:
|
|
440
|
+
findings = []
|
|
441
|
+
for motif in motifs:
|
|
442
|
+
normalized = _normalize_dna(motif)
|
|
443
|
+
if not normalized:
|
|
444
|
+
continue
|
|
445
|
+
start = seq.find(normalized)
|
|
446
|
+
while start != -1:
|
|
447
|
+
findings.append({"start": start, "end": start + len(normalized), "motif": normalized})
|
|
448
|
+
start = seq.find(normalized, start + 1)
|
|
449
|
+
return findings
|
|
423
450
|
|
|
424
451
|
|
|
425
452
|
def detect_invalid_codons(sequence: str) -> list[dict[str, Any]]:
|
|
@@ -998,8 +998,10 @@ def audit(sequence_fasta, reference_codon_profile, exclude_region, output):
|
|
|
998
998
|
|
|
999
999
|
|
|
1000
1000
|
from factorforge.nbfold.cli import nbfold_cli
|
|
1001
|
+
from factorforge.cli.structure_cli import structure_cli
|
|
1001
1002
|
|
|
1002
1003
|
cli.add_command(nbfold_cli)
|
|
1004
|
+
cli.add_command(structure_cli)
|
|
1003
1005
|
|
|
1004
1006
|
|
|
1005
1007
|
if __name__ == "__main__":
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"""Click CLI subcommands for FactorForge structure intake, sidecars, and Mol* viewer integration."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
import click
|
|
10
|
+
|
|
11
|
+
from factorforge.structure.interpro_sidecar_fetcher import fetch_interpro_sidecar
|
|
12
|
+
from factorforge.structure.uniprot_sidecar_fetcher import fetch_uniprot_sidecar
|
|
13
|
+
from factorforge.structure.viewer_bridge import (
|
|
14
|
+
build_structure_position_mapping,
|
|
15
|
+
prepare_viewer_annotations,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@click.group("structure")
|
|
20
|
+
def structure_cli() -> None:
|
|
21
|
+
"""Structure intake, UniProt/InterPro automated sidecars, and Mol* viewer integration."""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@structure_cli.command("fetch-uniprot")
|
|
25
|
+
@click.option("--accession", "-a", required=True, help="UniProt accession (e.g. P21926).")
|
|
26
|
+
@click.option("--sequence", "-s", default=None, help="Optional protein sequence to verify identity.")
|
|
27
|
+
@click.option("--output", "-o", type=click.Path(path_type=Path), help="Output path for JSON sidecar.")
|
|
28
|
+
@click.option("--cache-dir", type=click.Path(path_type=Path), default=None, help="Local cache directory.")
|
|
29
|
+
def fetch_uniprot_cmd(
|
|
30
|
+
accession: str,
|
|
31
|
+
sequence: Optional[str],
|
|
32
|
+
output: Optional[Path],
|
|
33
|
+
cache_dir: Optional[Path],
|
|
34
|
+
) -> None:
|
|
35
|
+
"""Fetch and normalize UniProt experimental/curated features into FactorForge sidecar."""
|
|
36
|
+
result = fetch_uniprot_sidecar(
|
|
37
|
+
accession=accession,
|
|
38
|
+
target_protein_sequence=sequence,
|
|
39
|
+
cache_dir=cache_dir,
|
|
40
|
+
)
|
|
41
|
+
payload_str = json.dumps(result, indent=2)
|
|
42
|
+
if output:
|
|
43
|
+
output.parent.mkdir(parents=True, exist_ok=True)
|
|
44
|
+
output.write_text(payload_str, encoding="utf-8")
|
|
45
|
+
click.echo(f"UniProt sidecar saved to {output} (status: {result.get('status')})")
|
|
46
|
+
else:
|
|
47
|
+
click.echo(payload_str)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@structure_cli.command("fetch-interpro")
|
|
51
|
+
@click.option("--accession", "-a", required=True, help="UniProt accession for InterPro entry search.")
|
|
52
|
+
@click.option("--sequence", "-s", required=True, help="Target protein sequence for coordinate bounds.")
|
|
53
|
+
@click.option("--output", "-o", type=click.Path(path_type=Path), help="Output path for JSON sidecar.")
|
|
54
|
+
@click.option("--cache-dir", type=click.Path(path_type=Path), default=None, help="Local cache directory.")
|
|
55
|
+
def fetch_interpro_cmd(
|
|
56
|
+
accession: str,
|
|
57
|
+
sequence: str,
|
|
58
|
+
output: Optional[Path],
|
|
59
|
+
cache_dir: Optional[Path],
|
|
60
|
+
) -> None:
|
|
61
|
+
"""Fetch and normalize InterPro domain families into FactorForge sidecar."""
|
|
62
|
+
result = fetch_interpro_sidecar(
|
|
63
|
+
accession=accession,
|
|
64
|
+
target_protein_sequence=sequence,
|
|
65
|
+
cache_dir=cache_dir,
|
|
66
|
+
)
|
|
67
|
+
payload_str = json.dumps(result, indent=2)
|
|
68
|
+
if output:
|
|
69
|
+
output.parent.mkdir(parents=True, exist_ok=True)
|
|
70
|
+
output.write_text(payload_str, encoding="utf-8")
|
|
71
|
+
click.echo(f"InterPro sidecar saved to {output} (status: {result.get('status')})")
|
|
72
|
+
else:
|
|
73
|
+
click.echo(payload_str)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@structure_cli.command("annotate")
|
|
77
|
+
@click.option("--accession", "-a", required=True, help="UniProt accession (e.g. P21926).")
|
|
78
|
+
@click.option("--structure-file", "--cif", type=click.Path(path_type=Path, exists=True), default=None, help="3D structure file (.cif, .mmcif, .pdb).")
|
|
79
|
+
@click.option("--chain", default="A", help="Structure chain ID (default: A).")
|
|
80
|
+
@click.option("--sequence", "-s", default=None, help="Optional protein sequence.")
|
|
81
|
+
@click.option("--interpro/--no-interpro", default=True, help="Whether to fetch InterPro domains.")
|
|
82
|
+
@click.option("--output", "-o", type=click.Path(path_type=Path), help="Output JSON path for consolidated annotations and viewer payload.")
|
|
83
|
+
@click.option("--cache-dir", type=click.Path(path_type=Path), default=None, help="Cache directory.")
|
|
84
|
+
def annotate_cmd(
|
|
85
|
+
accession: str,
|
|
86
|
+
structure_file: Optional[Path],
|
|
87
|
+
chain: str,
|
|
88
|
+
sequence: Optional[str],
|
|
89
|
+
interpro: bool,
|
|
90
|
+
output: Optional[Path],
|
|
91
|
+
cache_dir: Optional[Path],
|
|
92
|
+
) -> None:
|
|
93
|
+
"""Consolidate UniProt, InterPro, and 3D structure coordinates into verified Mol* viewer payload."""
|
|
94
|
+
click.echo(f"Fetching UniProt features for '{accession}'...")
|
|
95
|
+
uniprot_res = fetch_uniprot_sidecar(accession=accession, target_protein_sequence=sequence, cache_dir=cache_dir)
|
|
96
|
+
|
|
97
|
+
target_seq = sequence
|
|
98
|
+
if not target_seq and uniprot_res.get("status") == "AVAILABLE":
|
|
99
|
+
target_seq = uniprot_res.get("sequence", {}).get("value")
|
|
100
|
+
|
|
101
|
+
interpro_res = None
|
|
102
|
+
if interpro and target_seq:
|
|
103
|
+
click.echo(f"Fetching InterPro domains for '{accession}'...")
|
|
104
|
+
interpro_res = fetch_interpro_sidecar(accession=accession, target_protein_sequence=target_seq, cache_dir=cache_dir)
|
|
105
|
+
|
|
106
|
+
# Merge candidate regions
|
|
107
|
+
all_candidates = []
|
|
108
|
+
if uniprot_res.get("status") == "AVAILABLE":
|
|
109
|
+
all_candidates.extend(uniprot_res.get("candidate_regions", []))
|
|
110
|
+
if interpro_res and interpro_res.get("status") == "AVAILABLE":
|
|
111
|
+
all_candidates.extend(interpro_res.get("candidate_regions", []))
|
|
112
|
+
|
|
113
|
+
# Resolve 3D coordinates against structure if provided
|
|
114
|
+
position_mapping = None
|
|
115
|
+
if structure_file and target_seq:
|
|
116
|
+
click.echo(f"Mapping coordinates against structure '{structure_file.name}' chain '{chain}'...")
|
|
117
|
+
struct_text = structure_file.read_text(encoding="utf-8")
|
|
118
|
+
fmt = structure_file.suffix.lstrip(".").lower()
|
|
119
|
+
try:
|
|
120
|
+
position_mapping = build_structure_position_mapping(
|
|
121
|
+
protein_sequence=target_seq,
|
|
122
|
+
structure_content=struct_text,
|
|
123
|
+
format=fmt,
|
|
124
|
+
chain_id=chain,
|
|
125
|
+
)
|
|
126
|
+
click.echo(f"Successfully mapped {len(position_mapping)} residues to structure auth_seq_id.")
|
|
127
|
+
except Exception as exc:
|
|
128
|
+
click.echo(f"Warning: Structure coordinate mapping failed ({exc}). Falling back to unverified sequence indices.")
|
|
129
|
+
|
|
130
|
+
viewer_annotations = prepare_viewer_annotations(
|
|
131
|
+
{"candidate_regions": all_candidates},
|
|
132
|
+
auth_asym_id=chain,
|
|
133
|
+
position_mapping=position_mapping,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
consolidated = {
|
|
137
|
+
"accession": accession,
|
|
138
|
+
"protein_length": len(target_seq) if target_seq else None,
|
|
139
|
+
"structure_file": str(structure_file) if structure_file else None,
|
|
140
|
+
"chain_id": chain,
|
|
141
|
+
"coordinate_mapping_verified": position_mapping is not None,
|
|
142
|
+
"uniprot": uniprot_res,
|
|
143
|
+
"interpro": interpro_res,
|
|
144
|
+
"candidate_regions_total": len(all_candidates),
|
|
145
|
+
"viewer_annotations": viewer_annotations,
|
|
146
|
+
"reviewed": False, # Mandatory human review invariant
|
|
147
|
+
"epistemic_status": "UNVERIFIED_PUBLIC_CORPUS",
|
|
148
|
+
"biological_validation": "NOT_AVAILABLE",
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
out_json = json.dumps(consolidated, indent=2)
|
|
152
|
+
if output:
|
|
153
|
+
output.parent.mkdir(parents=True, exist_ok=True)
|
|
154
|
+
output.write_text(out_json, encoding="utf-8")
|
|
155
|
+
click.echo(f"Consolidated annotation report & viewer payload saved to {output}")
|
|
156
|
+
else:
|
|
157
|
+
click.echo(out_json)
|
|
@@ -20,6 +20,13 @@ def _load_dp_v2_3():
|
|
|
20
20
|
return DPV230EngineAdapter
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
def _load_dp_v2_4():
|
|
24
|
+
"""Load DP v2.4.0 engine when requested."""
|
|
25
|
+
from .dp_v2_4 import DPV240EngineAdapter
|
|
26
|
+
|
|
27
|
+
return DPV240EngineAdapter
|
|
28
|
+
|
|
29
|
+
|
|
23
30
|
def register_builtin_engines() -> None:
|
|
24
31
|
"""Register bundled engines."""
|
|
25
32
|
from .profile.optimizer import RuleBasedOptimizer
|
|
@@ -37,6 +44,12 @@ def register_builtin_engines() -> None:
|
|
|
37
44
|
metadata={**engine_metadata("dp_v2_3"), "stable": False},
|
|
38
45
|
)
|
|
39
46
|
|
|
47
|
+
EngineRegistry.register_lazy(
|
|
48
|
+
"dp_v2_4",
|
|
49
|
+
_load_dp_v2_4,
|
|
50
|
+
metadata={**engine_metadata("dp_v2_4"), "stable": False},
|
|
51
|
+
)
|
|
52
|
+
|
|
40
53
|
EngineRegistry.register(
|
|
41
54
|
"profile",
|
|
42
55
|
RuleBasedOptimizer,
|