factorforge-cds 3.2.7__tar.gz → 3.2.8__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.2.7/src/factorforge_cds.egg-info → factorforge_cds-3.2.8}/PKG-INFO +2 -2
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/README.md +1 -1
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/pyproject.toml +1 -1
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/__init__.py +1 -1
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/analysis/feasibility.py +11 -14
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/cli/main.py +2 -2
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/__init__.py +1 -1
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/__init__.py +1 -1
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/optimizer.py +1 -1
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/rules/reverse_translator.py +6 -5
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/rules/rule_engine.py +8 -6
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/scoring.py +18 -14
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/utils.py +7 -8
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8/src/factorforge_cds.egg-info}/PKG-INFO +2 -2
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_registry_production_sync.py +23 -3
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_worked_example.py +10 -5
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/LICENSE +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/setup.cfg +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/__main__.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/analysis/__init__.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/analysis/metrics.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/cli/__init__.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/cli/legacy_cli.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/core/interfaces/__init__.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/core/interfaces/exporter.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/core/interfaces/optimizer.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/core/interfaces/validator.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/data/nbenthamiana_codons.json +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/data/nbenthamiana_golden_set.json +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/data/ntabacum_codons.json +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/data/templates/high_expression.json +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/data/templates/standard_expression.json +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/data/wolffia_globosa_codons.json +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/database.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/codon_table_builder.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/construct_builder.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/exporter.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/pipeline.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/rules/__init__.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/rules/domesticator.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/scoring_ml.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/validator.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/registry.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/io/__init__.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/io/fasta.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/io/validation.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/protein_risk/__init__.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/protein_risk/annotate.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/protein_risk/kd_scale.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/protein_risk/risk_classifier.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/protein_risk/sp_predict.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/protein_risk/tm_predict.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/registry/__init__.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/registry/registry_loader.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/schemas/__init__.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/schemas/design_package.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/schemas/design_package.schema.json +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/utils/__init__.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/utils/construct_id.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/utils/exceptions.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/utils/restriction_sites.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/utils/sequence_validator.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/utils/validation.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/validation/__init__.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/validation/cli.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/validation/package_generator.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/validation_registry.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/validation_report.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge_cds.egg-info/SOURCES.txt +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge_cds.egg-info/dependency_links.txt +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge_cds.egg-info/entry_points.txt +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge_cds.egg-info/requires.txt +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge_cds.egg-info/top_level.txt +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_baselines.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_benchmark_codon_table_metadata.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_benchmark_regression.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_benchmark_scoring.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_benchmark_smoke.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_cai.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_codon_table_manifest.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_database.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_design_package_schema.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_design_package_semantics.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_design_package_serialization.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_docs_consistency.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_fasta_io.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_gc_content.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_host_profile_metadata.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_iupac_validation.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_legacy_cli.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_no_raw_sequence_logging.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_openbio_missing_metric_contract.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_parameter_registry.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_protein_risk.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_restriction_sites.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_sequence_validator.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_translation_integrity.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_validation_contract_compat.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_validation_registry.py +0 -0
- {factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_validation_report.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: factorforge-cds
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.8
|
|
4
4
|
Summary: FactorForge - open-source CDS design and pre-synthesis sequence review engine by Eijex.
|
|
5
5
|
Author-email: Eijex <eijex.lab@gmail.com>
|
|
6
6
|
License-Expression: AGPL-3.0-only
|
|
@@ -93,7 +93,7 @@ FactorForge outputs are **in-silico only** and have not been experimentally vali
|
|
|
93
93
|
## Citing
|
|
94
94
|
|
|
95
95
|
```
|
|
96
|
-
FactorForge v3.2.
|
|
96
|
+
FactorForge v3.2.8 (2026). Open-source constraint-based CDS design engine.
|
|
97
97
|
Eijex. https://github.com/eijex/factorforge-cds
|
|
98
98
|
```
|
|
99
99
|
|
|
@@ -60,7 +60,7 @@ FactorForge outputs are **in-silico only** and have not been experimentally vali
|
|
|
60
60
|
## Citing
|
|
61
61
|
|
|
62
62
|
```
|
|
63
|
-
FactorForge v3.2.
|
|
63
|
+
FactorForge v3.2.8 (2026). Open-source constraint-based CDS design engine.
|
|
64
64
|
Eijex. https://github.com/eijex/factorforge-cds
|
|
65
65
|
```
|
|
66
66
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "factorforge-cds"
|
|
7
|
-
version = "3.2.
|
|
7
|
+
version = "3.2.8"
|
|
8
8
|
description = "FactorForge - open-source CDS design and pre-synthesis sequence review engine by Eijex."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "AGPL-3.0-only"
|
|
@@ -14,18 +14,19 @@ from factorforge.analysis.metrics import (
|
|
|
14
14
|
)
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
#
|
|
18
|
-
# (internal benchmark, n=49
|
|
19
|
-
#
|
|
20
|
-
# (_analysis/025 STEP 2: 004 endogenous n=10 measured range 40-47%, cross-checked
|
|
21
|
-
# against nbev11_cds_hc/all and qld183_v103 derived-asset GC ~42.8-43.1% and
|
|
22
|
-
# external ground truth ~44%). NOT an empirically validated expression optimum —
|
|
23
|
-
# this is a composition anchor, not a target to maximize toward.
|
|
17
|
+
# Defaults calibrated to nbenthamiana profile engine output distribution
|
|
18
|
+
# (internal benchmark, n=49): avg CAI=0.76, avg GC=60.1% (range 55-71%).
|
|
19
|
+
# DEFAULT_CAI_TARGET=0.82 aligns with industry practice (>0.8) and is achievable.
|
|
24
20
|
# Exported as named constants so tests/test_registry_production_sync.py can
|
|
25
21
|
# strictly compare them against the registry (single source of truth).
|
|
22
|
+
#
|
|
23
|
+
# DEFAULT_GC_LOW/HIGH provisionally reverted from the Job 168/v3.3.0
|
|
24
|
+
# native-genome-composition anchor (40-47%, released as part of v3.2.7) back
|
|
25
|
+
# to the legacy engine-output-calibrated band, pending an MFE re-sensitivity +
|
|
26
|
+
# 2x2 factorial recheck. See scoring.py's GC_OPT_MIN/MAX comment.
|
|
26
27
|
DEFAULT_CAI_TARGET: float = 0.82
|
|
27
|
-
DEFAULT_GC_LOW: float =
|
|
28
|
-
DEFAULT_GC_HIGH: float =
|
|
28
|
+
DEFAULT_GC_LOW: float = 55.0
|
|
29
|
+
DEFAULT_GC_HIGH: float = 65.0
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
AA_TO_CODONS: dict[str, list[str]] = {}
|
|
@@ -120,11 +121,7 @@ def analyze_feasibility(
|
|
|
120
121
|
if not protein:
|
|
121
122
|
raise ValueError("protein_sequence must not be empty")
|
|
122
123
|
|
|
123
|
-
|
|
124
|
-
# progressively wider windows. (55.0, 65.0) is retained ONLY as an explicit
|
|
125
|
-
# non-native/high-GC option (matches legacy engine-output-calibrated band) —
|
|
126
|
-
# callers must opt in explicitly to it, it is not the production default.
|
|
127
|
-
ranges = gc_ranges or [(40.0, 47.0), (35.0, 50.0), (55.0, 65.0)]
|
|
124
|
+
ranges = gc_ranges or [(55.0, 65.0), (50.0, 65.0), (40.0, 65.0)]
|
|
128
125
|
normalized_ranges = [
|
|
129
126
|
(_normalize_gc_bound(low), _normalize_gc_bound(high)) for low, high in ranges
|
|
130
127
|
]
|
|
@@ -164,8 +164,8 @@ def list_engines():
|
|
|
164
164
|
type=click.Choice(["feasibility_best"], case_sensitive=False),
|
|
165
165
|
help="DP objective",
|
|
166
166
|
)
|
|
167
|
-
@click.option("--gc-min", type=float, default=
|
|
168
|
-
@click.option("--gc-max", type=float, default=
|
|
167
|
+
@click.option("--gc-min", type=float, default=55.0, help="Minimum target GC percentage")
|
|
168
|
+
@click.option("--gc-max", type=float, default=65.0, help="Maximum target GC percentage")
|
|
169
169
|
@click.option("--template", "construct_template", help="Construct template name")
|
|
170
170
|
@click.option("--output", "-o", help="Output file")
|
|
171
171
|
@click.option("--format", "output_format", default="fasta", help="Output format (fasta, genbank)")
|
|
@@ -374,11 +374,12 @@ class ReverseTranslator:
|
|
|
374
374
|
Balanced profile: CAI first, GC balanced
|
|
375
375
|
|
|
376
376
|
- Preferred codon ratio: 70%
|
|
377
|
-
- Target GC: host composition band
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
377
|
+
- Target GC: host composition band, resolved via
|
|
378
|
+
resolve_host_gc_range() (engines/profile/scoring.py
|
|
379
|
+
GC_OPT_MIN/MAX). nbenthamiana currently uses the legacy 55-65%
|
|
380
|
+
band; the native genome-composition anchor (40-47%, _analysis/025)
|
|
381
|
+
was provisionally reverted on 2026-06-29 pending an MFE
|
|
382
|
+
re-sensitivity + 2x2 factorial recheck.
|
|
382
383
|
"""
|
|
383
384
|
_host_gc_min, _host_gc_max = resolve_host_gc_range(self.host)
|
|
384
385
|
target_gc_min = kwargs.get("target_gc_min", _host_gc_min)
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/rules/rule_engine.py
RENAMED
|
@@ -358,12 +358,14 @@ class RuleEngine:
|
|
|
358
358
|
|
|
359
359
|
This is a LOCAL synthesis/extreme-window guard (default 25-75% over a
|
|
360
360
|
50 bp window), NOT the global GC target. Global GC is governed separately
|
|
361
|
-
by the scoring band (GC_OPT_MIN/MAX,
|
|
362
|
-
~40-47%,
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
361
|
+
by the scoring band (GC_OPT_MIN/MAX, currently 55-65% for nbenthamiana
|
|
362
|
+
— the native genome-composition anchor, ~40-47%, _analysis/025, was
|
|
363
|
+
provisionally reverted on 2026-06-29 pending an MFE re-sensitivity +
|
|
364
|
+
2x2 factorial recheck) and the API/DP gc_min/gc_max constraints. The
|
|
365
|
+
wide 25-75% local band is an independent synthesis/hairpin-risk guard
|
|
366
|
+
(registry `gc_extreme_local_window`), not derived from or coupled to
|
|
367
|
+
the global GC target — narrowing it is a separate decision from the
|
|
368
|
+
global band retarget and is out of scope here.
|
|
367
369
|
|
|
368
370
|
Args:
|
|
369
371
|
seq: DNA sequence
|
|
@@ -12,22 +12,26 @@ from typing import Any
|
|
|
12
12
|
logger = logging.getLogger(__name__)
|
|
13
13
|
|
|
14
14
|
# GC band for N. benthamiana codon-optimized sequences.
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
# Benchmark (internal, n=49): balanced profile output average GC% = 60.1%
|
|
16
|
+
# (range 55-71%). The genome-wide average (~42%) reflects all genes, not the
|
|
17
|
+
# high-expression codon table which exhibits 3rd-position GC bias.
|
|
18
|
+
# These constants define the acceptable band — sequences within [GC_OPT_MIN, GC_OPT_MAX]
|
|
19
|
+
# receive full GC score; outside the band the score decays linearly.
|
|
20
|
+
#
|
|
21
|
+
# Job 168/v3.3.0 (released as part of v3.2.7, see CHANGELOG) moved this band to
|
|
22
|
+
# 40-47% (native genome-composition anchor, _analysis/025). Provisionally
|
|
23
|
+
# reverted here pending an MFE re-sensitivity + 2x2 factorial recheck
|
|
24
|
+
# (_analysis, scope TBD as of 2026-06-29) — see eijex-workspace
|
|
25
|
+
# _version/factorforge-version-sequencing-plan.md. Not a rejection of the
|
|
26
|
+
# 40-47% anchor, just not yet re-confirmed as the production default.
|
|
27
|
+
GC_OPT_MIN = 55.0
|
|
28
|
+
GC_OPT_MAX = 65.0
|
|
29
|
+
GC_OPT_MID = 60.0 # kept for gc_target point-scoring and viral_delivery centering
|
|
24
30
|
GC_DECAY_WIDTH = 20.0 # percentage points outside band before score reaches 0.0
|
|
25
31
|
|
|
26
|
-
# Job 168
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
# their own host-specific genome-composition analysis — they must NOT silently
|
|
30
|
-
# inherit GC_OPT_MIN/MAX, which is an N.-benthamiana-specific anchor.
|
|
32
|
+
# Host-isolation fix (Job 168/v3.3.0, kept): ntabacum/BY-2 must not silently
|
|
33
|
+
# inherit whatever band nbenthamiana uses. Both currently resolve to the same
|
|
34
|
+
# GC_RANGE_DEFAULT band pending the nbenthamiana re-check above.
|
|
31
35
|
GC_RANGE_DEFAULT: tuple[float, float] = (55.0, 65.0)
|
|
32
36
|
GC_RANGES_BY_HOST: dict[str, tuple[float, float]] = {
|
|
33
37
|
"nbenthamiana": (GC_OPT_MIN, GC_OPT_MAX),
|
|
@@ -115,14 +115,13 @@ def calculate_dinucleotide_ratio(sequence: str, dinucleotide: str = "CG") -> flo
|
|
|
115
115
|
return observed / expected
|
|
116
116
|
|
|
117
117
|
|
|
118
|
-
# Job 168 / v3.3.0 (_analysis/025)
|
|
119
|
-
#
|
|
120
|
-
#
|
|
121
|
-
#
|
|
122
|
-
#
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
118
|
+
# Job 168 / v3.3.0 (_analysis/025) introduced a host -> production-default
|
|
119
|
+
# codon table file override mechanism and pointed nbenthamiana at the NbeV1.1
|
|
120
|
+
# LAB-strain derived table (released as part of v3.2.7). Provisionally
|
|
121
|
+
# reverted to empty (falls back to the legacy {host}_codons.json convention)
|
|
122
|
+
# pending an MFE re-sensitivity + 2x2 factorial recheck. The NbeV1.1 table
|
|
123
|
+
# remains on disk and selectable; see data/reference/active_codon_reference.json.
|
|
124
|
+
_HOST_CODON_TABLE_OVERRIDES: dict[str, str] = {}
|
|
126
125
|
|
|
127
126
|
|
|
128
127
|
def resolve_host_codon_table_path(host: str, codon_tables_dir: Path) -> Path:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: factorforge-cds
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.8
|
|
4
4
|
Summary: FactorForge - open-source CDS design and pre-synthesis sequence review engine by Eijex.
|
|
5
5
|
Author-email: Eijex <eijex.lab@gmail.com>
|
|
6
6
|
License-Expression: AGPL-3.0-only
|
|
@@ -93,7 +93,7 @@ FactorForge outputs are **in-silico only** and have not been experimentally vali
|
|
|
93
93
|
## Citing
|
|
94
94
|
|
|
95
95
|
```
|
|
96
|
-
FactorForge v3.2.
|
|
96
|
+
FactorForge v3.2.8 (2026). Open-source constraint-based CDS design engine.
|
|
97
97
|
Eijex. https://github.com/eijex/factorforge-cds
|
|
98
98
|
```
|
|
99
99
|
|
|
@@ -103,16 +103,18 @@ def test_codon_reference_active_sync_with_active_reference_file():
|
|
|
103
103
|
assert registry_active["sha256"] == hashlib.sha256(table_path.read_bytes()).hexdigest()
|
|
104
104
|
|
|
105
105
|
|
|
106
|
-
def
|
|
106
|
+
def test_codon_reference_active_sync_with_legacy_manifest():
|
|
107
107
|
"""registry's codon_reference.active block must match the schema-conformant
|
|
108
|
-
|
|
108
|
+
legacy (v1) manifest file's facts (asset_type, sha256, source_status) — v1
|
|
109
|
+
is the production default again as of the v3.2.7 GC-band/codon-reference
|
|
110
|
+
revert, pending an MFE re-sensitivity + 2x2 factorial recheck of v2."""
|
|
109
111
|
import json
|
|
110
112
|
from pathlib import Path
|
|
111
113
|
|
|
112
114
|
registry_active = _resolve("codon_reference.active")
|
|
113
115
|
manifest = json.loads(
|
|
114
116
|
(Path(__file__).resolve().parents[1] / "data" / "reference"
|
|
115
|
-
/ "
|
|
117
|
+
/ "codon_table_manifest.json").read_text(encoding="utf-8")
|
|
116
118
|
)
|
|
117
119
|
assert registry_active["id"] == manifest["codon_table_id"]
|
|
118
120
|
assert registry_active["sha256"] == manifest["sha256"]
|
|
@@ -120,6 +122,24 @@ def test_codon_reference_active_sync_with_v2_manifest():
|
|
|
120
122
|
assert registry_active["source_status"] == manifest["source_status"]
|
|
121
123
|
|
|
122
124
|
|
|
125
|
+
def test_codon_reference_candidate_sync_with_v2_manifest():
|
|
126
|
+
"""registry's codon_reference.candidate block (the provisionally
|
|
127
|
+
un-promoted v2 asset) must stay in sync with its own manifest file even
|
|
128
|
+
while not active."""
|
|
129
|
+
import json
|
|
130
|
+
from pathlib import Path
|
|
131
|
+
|
|
132
|
+
registry_candidate = _resolve("codon_reference.candidate")
|
|
133
|
+
manifest = json.loads(
|
|
134
|
+
(Path(__file__).resolve().parents[1] / "data" / "reference"
|
|
135
|
+
/ "codon_table_manifest_nbev11_hc_v2.json").read_text(encoding="utf-8")
|
|
136
|
+
)
|
|
137
|
+
assert registry_candidate["id"] == manifest["codon_table_id"]
|
|
138
|
+
assert registry_candidate["sha256"] == manifest["sha256"]
|
|
139
|
+
assert registry_candidate["asset_type"] == manifest["asset_type"]
|
|
140
|
+
assert registry_candidate["source_status"] == manifest["source_status"]
|
|
141
|
+
|
|
142
|
+
|
|
123
143
|
def test_codon_reference_active_table_sha256_matches_production_default():
|
|
124
144
|
"""The sha256 recorded for the active codon_reference must match the
|
|
125
145
|
actual file the production engine resolves to by default."""
|
|
@@ -82,10 +82,14 @@ def test_run_example_deterministic():
|
|
|
82
82
|
|
|
83
83
|
|
|
84
84
|
def test_run_example_v2_smoke_succeeds():
|
|
85
|
-
"""run_example_v2_smoke.py (
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
"""run_example_v2_smoke.py (tracks whatever the current production
|
|
86
|
+
default actually is) must exit 0 and report a provenance ID that matches
|
|
87
|
+
data/reference/active_codon_reference.json — not hardcoded to v2, since
|
|
88
|
+
the default was provisionally reverted to v1 on 2026-06-29 pending an MFE
|
|
89
|
+
re-sensitivity + 2x2 factorial recheck (Job 168 / v3.3.0, _analysis/025).
|
|
90
|
+
|
|
91
|
+
No frozen-output comparison — this only checks that the current-default
|
|
92
|
+
path runs end-to-end and reports correct provenance.
|
|
89
93
|
"""
|
|
90
94
|
result = subprocess.run(
|
|
91
95
|
[sys.executable, str(EXAMPLE_DIR / "run_example_v2_smoke.py")],
|
|
@@ -98,7 +102,8 @@ def test_run_example_v2_smoke_succeeds():
|
|
|
98
102
|
f"stdout:{result.stdout}\nstderr:{result.stderr}"
|
|
99
103
|
)
|
|
100
104
|
assert "OK" in result.stdout
|
|
101
|
-
|
|
105
|
+
active_ref = _load(ROOT / "data" / "reference" / "active_codon_reference.json")
|
|
106
|
+
assert active_ref["active_codon_table_id"] in result.stdout
|
|
102
107
|
|
|
103
108
|
|
|
104
109
|
# ---------------------------------------------------------------------------
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/core/interfaces/optimizer.py
RENAMED
|
File without changes
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/core/interfaces/validator.py
RENAMED
|
File without changes
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/data/nbenthamiana_codons.json
RENAMED
|
File without changes
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/data/nbenthamiana_golden_set.json
RENAMED
|
File without changes
|
|
File without changes
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/data/templates/high_expression.json
RENAMED
|
File without changes
|
|
File without changes
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/data/wolffia_globosa_codons.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/construct_builder.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/rules/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/scoring_ml.py
RENAMED
|
File without changes
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/engines/profile/validator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/protein_risk/risk_classifier.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/schemas/design_package.schema.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge/validation/package_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge_cds.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/src/factorforge_cds.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_benchmark_codon_table_metadata.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{factorforge_cds-3.2.7 → factorforge_cds-3.2.8}/tests/test_openbio_missing_metric_contract.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|